CQ. In DartObjectPrinter print full types of List, Set, Map values. Switch more tests to assertDartObjectText().

Change-Id: I66e078e571e9a5e803aed60911b519fe09d1ce7a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/508440
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Konstantin Shcheglov
2026-06-02 10:55:35 -07:00
parent fe53326c60
commit b389e23feb
3 changed files with 209 additions and 204 deletions
@@ -4,7 +4,6 @@
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/constant/evaluation.dart';
@@ -1254,8 +1253,7 @@ const x = <E>[];
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, '''
List
elementType: int
List<int>
variable: <testLibrary>::@topLevelVariable::x
typeNotExtensionTypeErased: List<E>
''');
@@ -1269,8 +1267,7 @@ const x = [E(0), E(1)];
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, '''
List
elementType: int
List<int>
elements
int 0
typeNotExtensionTypeErased: E
@@ -1289,7 +1286,7 @@ const x = {E(0): E(1)};
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, '''
Map
Map<int, int>
entries
entry
key: int 0
@@ -2861,8 +2858,7 @@ const x = <String>['a', 'b', 'c'];
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, r'''
List
elementType: String
List<String>
elements
String a
String b
@@ -2877,8 +2873,7 @@ const x = <void Function()>[];
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, r'''
List
elementType: void Function()
List<void Function()>
variable: <testLibrary>::@topLevelVariable::x
''');
}
@@ -2911,8 +2906,7 @@ const x = ['a', 'b', 'c'];
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, r'''
List
elementType: String
List<String>
elements
String a
String b
@@ -2929,8 +2923,7 @@ const c = [a, 1, b];
''');
var result = _topLevelVar(unitResult, 'c');
assertDartObjectText(result, r'''
List
elementType: int
List<int>
elements
int 0
variable: <testLibrary>::@topLevelVariable::a
@@ -2962,8 +2955,7 @@ const List<String> x = [
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, '''
List
elementType: String
List<String>
elements
String anotherString
variable: <testLibrary>::@topLevelVariable::x
@@ -2980,8 +2972,7 @@ const List<String> x = [
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, '''
List
elementType: String
List<String>
elements
String anotherString
String string
@@ -3464,7 +3455,7 @@ const x = {A(0): 1, fn: 2};
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, r'''
Map
Map<Object, int>
entries
entry
key: A
@@ -3523,7 +3514,7 @@ const x = {'a' : 'm', 'b' : 'n', 'c' : 'o'};
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, '''
Map
Map<String, String>
entries
entry
key: String a
@@ -3548,7 +3539,7 @@ const Map<String, int> alwaysInclude = {
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, '''
Map
Map<String, int>
entries
entry
key: String string
@@ -3580,7 +3571,7 @@ const Map<String, int> x = {
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, '''
Map
Map<String, int>
entries
entry
key: String anotherString
@@ -3603,7 +3594,7 @@ const a = {cp0, cm0};
''');
var result = _topLevelVar(unitResult, 'a');
assertDartObjectText(result, '''
Set
Set<C>
elements
C
x: double 0.0
@@ -3657,7 +3648,7 @@ const Set<String> x = {
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, '''
Set
Set<String>
elements
String anotherString
String string
@@ -3675,7 +3666,7 @@ const Set<String> x = {
''');
var result = _topLevelVar(unitResult, 'x');
assertDartObjectText(result, '''
Set
Set<String>
elements
String anotherString
variable: <testLibrary>::@topLevelVariable::x
@@ -3900,269 +3891,288 @@ mixin ConstantVisitorTestCases on ConstantVisitorTestSupport {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = [1, if (1 < 0) 2 else 3, 4];
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.listType(unitResult.typeProvider.intType),
);
expect(result.toListValue()!.map((e) => e.toIntValue()), [1, 3, 4]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
List<int>
elements
int 1
int 3
int 4
''');
}
test_listLiteral_ifElement_false_withoutElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = [1, if (1 < 0) 2, 3];
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.listType(unitResult.typeProvider.intType),
);
expect(result.toListValue()!.map((e) => e.toIntValue()), [1, 3]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
List<int>
elements
int 1
int 3
''');
}
test_listLiteral_ifElement_true_withElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = [1, if (1 > 0) 2 else 3, 4];
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.listType(unitResult.typeProvider.intType),
);
expect(result.toListValue()!.map((e) => e.toIntValue()), [1, 2, 4]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
List<int>
elements
int 1
int 2
int 4
''');
}
test_listLiteral_ifElement_true_withoutElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = [1, if (1 > 0) 2, 3];
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.listType(unitResult.typeProvider.intType),
);
expect(result.toListValue()!.map((e) => e.toIntValue()), [1, 2, 3]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
List<int>
elements
int 1
int 2
int 3
''');
}
test_listLiteral_nested() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = [1, if (1 > 0) if (2 > 1) 2, 3];
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
// The expected type ought to be `List<int>`, but type inference isn't yet
// implemented.
expect(
result.type,
unitResult.typeProvider.listType(unitResult.typeProvider.intType),
);
expect(result.toListValue()!.map((e) => e.toIntValue()), [1, 2, 3]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
List<int>
elements
int 1
int 2
int 3
''');
}
test_listLiteral_spreadElement() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = [1, ...[2, 3], 4];
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.listType(unitResult.typeProvider.intType),
);
expect(result.toListValue()!.map((e) => e.toIntValue()), [1, 2, 3, 4]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
List<int>
elements
int 1
int 2
int 3
int 4
''');
}
test_mapLiteral_ifElement_false_withElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {'a' : 1, if (1 < 0) 'b' : 2 else 'c' : 3, 'd' : 4};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.mapType(
unitResult.typeProvider.stringType,
unitResult.typeProvider.intType,
),
);
Map<DartObject, DartObject> value = result.toMapValue()!;
expect(
value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'c', 'd']),
);
expect(value.values.map((e) => e.toIntValue()), unorderedEquals([1, 3, 4]));
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Map<String, int>
entries
entry
key: String a
value: int 1
entry
key: String c
value: int 3
entry
key: String d
value: int 4
''');
}
test_mapLiteral_ifElement_false_withoutElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {'a' : 1, if (1 < 0) 'b' : 2, 'c' : 3};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.mapType(
unitResult.typeProvider.stringType,
unitResult.typeProvider.intType,
),
);
Map<DartObject, DartObject> value = result.toMapValue()!;
expect(
value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'c']),
);
expect(value.values.map((e) => e.toIntValue()), unorderedEquals([1, 3]));
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Map<String, int>
entries
entry
key: String a
value: int 1
entry
key: String c
value: int 3
''');
}
test_mapLiteral_ifElement_true_withElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {'a' : 1, if (1 > 0) 'b' : 2 else 'c' : 3, 'd' : 4};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.mapType(
unitResult.typeProvider.stringType,
unitResult.typeProvider.intType,
),
);
Map<DartObject, DartObject> value = result.toMapValue()!;
expect(
value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'b', 'd']),
);
expect(value.values.map((e) => e.toIntValue()), unorderedEquals([1, 2, 4]));
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Map<String, int>
entries
entry
key: String a
value: int 1
entry
key: String b
value: int 2
entry
key: String d
value: int 4
''');
}
test_mapLiteral_ifElement_true_withoutElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {'a' : 1, if (1 > 0) 'b' : 2, 'c' : 3};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.mapType(
unitResult.typeProvider.stringType,
unitResult.typeProvider.intType,
),
);
Map<DartObject, DartObject> value = result.toMapValue()!;
expect(
value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'b', 'c']),
);
expect(value.values.map((e) => e.toIntValue()), unorderedEquals([1, 2, 3]));
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Map<String, int>
entries
entry
key: String a
value: int 1
entry
key: String b
value: int 2
entry
key: String c
value: int 3
''');
}
test_mapLiteral_nested() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {'a' : 1, if (1 > 0) if (2 > 1) ...{'b' : 2}, 'c' : 3};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.mapType(
unitResult.typeProvider.stringType,
unitResult.typeProvider.intType,
),
);
Map<DartObject, DartObject> value = result.toMapValue()!;
expect(
value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'b', 'c']),
);
expect(value.values.map((e) => e.toIntValue()), unorderedEquals([1, 2, 3]));
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Map<String, int>
entries
entry
key: String a
value: int 1
entry
key: String b
value: int 2
entry
key: String c
value: int 3
''');
}
test_mapLiteral_spreadElement() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {'a' : 1, ...{'b' : 2, 'c' : 3}, 'd' : 4};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.mapType(
unitResult.typeProvider.stringType,
unitResult.typeProvider.intType,
),
);
Map<DartObject, DartObject> value = result.toMapValue()!;
expect(
value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'b', 'c', 'd']),
);
expect(
value.values.map((e) => e.toIntValue()),
unorderedEquals([1, 2, 3, 4]),
);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Map<String, int>
entries
entry
key: String a
value: int 1
entry
key: String b
value: int 2
entry
key: String c
value: int 3
entry
key: String d
value: int 4
''');
}
test_setLiteral_ifElement_false_withElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {1, if (1 < 0) 2 else 3, 4};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.setType(unitResult.typeProvider.intType),
);
expect(result.toSetValue()!.map((e) => e.toIntValue()), [1, 3, 4]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Set<int>
elements
int 1
int 3
int 4
''');
}
test_setLiteral_ifElement_false_withoutElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {1, if (1 < 0) 2, 3};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.setType(unitResult.typeProvider.intType),
);
expect(result.toSetValue()!.map((e) => e.toIntValue()), [1, 3]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Set<int>
elements
int 1
int 3
''');
}
test_setLiteral_ifElement_true_withElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {1, if (1 > 0) 2 else 3, 4};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.setType(unitResult.typeProvider.intType),
);
expect(result.toSetValue()!.map((e) => e.toIntValue()), [1, 2, 4]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Set<int>
elements
int 1
int 2
int 4
''');
}
test_setLiteral_ifElement_true_withoutElse() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {1, if (1 > 0) 2, 3};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.setType(unitResult.typeProvider.intType),
);
expect(result.toSetValue()!.map((e) => e.toIntValue()), [1, 2, 3]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Set<int>
elements
int 1
int 2
int 3
''');
}
test_setLiteral_nested() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {1, if (1 > 0) if (2 > 1) 2, 3};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.setType(unitResult.typeProvider.intType),
);
expect(result.toSetValue()!.map((e) => e.toIntValue()), [1, 2, 3]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Set<int>
elements
int 1
int 2
int 3
''');
}
test_setLiteral_spreadElement() async {
var unitResult = await resolveTestCodeWithDiagnostics('''
const c = {1, ...{2, 3}, 4};
''');
DartObjectImpl result = _evaluateConstant(unitResult, 'c');
expect(
result.type,
unitResult.typeProvider.setType(unitResult.typeProvider.intType),
);
expect(result.toSetValue()!.map((e) => e.toIntValue()), [1, 2, 3, 4]);
var result = _evaluateConstant(unitResult, 'c');
assertDartObjectText(result, '''
Set<int>
elements
int 1
int 2
int 3
int 4
''');
}
test_visitAdjacentInterpolation_simple() async {
@@ -47,13 +47,13 @@ class DartObjectPrinter {
} else if (state is GenericState) {
_writeGenericState(type, state);
} else if (state is ListState) {
_writeListState(state);
_writeListState(type, state);
} else if (state is MapState) {
_writeMapState(state);
_writeMapState(type, state);
} else if (state is RecordState) {
_writeRecordState(type, state);
} else if (state is SetState) {
_writeSetState(state);
_writeSetState(type, state);
} else if (state is TypeState) {
_writeTypeObject(object);
} else {
@@ -132,10 +132,9 @@ class DartObjectPrinter {
}
}
void _writeListState(ListState state) {
_sink.writeln('List');
void _writeListState(DartType type, ListState state) {
_writelnType(type);
_sink.withIndent(() {
_elementPrinter.writeNamedType('elementType', state.elementType);
var elements = state.elements;
if (elements.isNotEmpty) {
_sink.writelnWithIndent('elements');
@@ -159,8 +158,8 @@ class DartObjectPrinter {
}
}
void _writeMapState(MapState state) {
_sink.writeln('Map');
void _writeMapState(DartType type, MapState state) {
_writelnType(type);
_sink.withIndent(() {
var entries = state.entries;
if (entries.isNotEmpty) {
@@ -215,8 +214,8 @@ class DartObjectPrinter {
});
}
void _writeSetState(SetState state) {
_sink.writeln('Set');
void _writeSetState(DartType type, SetState state) {
_writelnType(type);
_sink.withIndent(() {
var elements = state.elements;
if (elements.isNotEmpty) {
@@ -855,15 +855,13 @@ Annotation
''');
_assertAnnotationValueText(node, '''
A<Object?>
f: List
elementType: List<Object?>
f: List<List<Object?>>
constructorInvocation
constructor: ConstructorMember
baseElement: <testLibrary>::@class::A::@constructor::named
substitution: {T: Object?}
positionalArguments
0: List
elementType: List<Object?>
0: List<List<Object?>>
''');
}
@@ -903,15 +901,13 @@ Annotation
''');
_assertAnnotationValueText(node, r'''
A<Object?>
f: List
elementType: List<Object?>
f: List<List<Object?>>
constructorInvocation
constructor: ConstructorMember
baseElement: <testLibrary>::@class::A::@constructor::new
substitution: {T: Object?}
positionalArguments
0: List
elementType: List<Object?>
0: List<List<Object?>>
''');
}