[vm, service] Report InstanceKind for Sets.
(The elements were already being populated.)
TEST=ci
Change-Id: I02cfa2f311e7871836f1eddd8ed131c282235d58
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/269383
Reviewed-by: Ben Konyi <bkonyi@google.com>
Reviewed-by: Derek Xu <derekx@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 9f30e1c..9331689 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -2691,6 +2691,10 @@
/// be PlainInstance.
static const String kMap = 'Map';
+ /// An instance of the built-in VM Set implementation. User-defined Sets will
+ /// be PlainInstance.
+ static const String kSet = 'Set';
+
/// Vector instance kinds.
static const String kFloat32x4 = 'Float32x4';
static const String kFloat64x2 = 'Float64x2';
diff --git a/pkg/vm_service/test/get_object_rpc_test.dart b/pkg/vm_service/test/get_object_rpc_test.dart
index d84c844..c722d98 100644
--- a/pkg/vm_service/test/get_object_rpc_test.dart
+++ b/pkg/vm_service/test/get_object_rpc_test.dart
@@ -55,6 +55,9 @@
getMap() => {"x": 3, "y": 4, "z": 5};
@pragma("vm:entry-point")
+getSet() => {6, 7, 8};
+
+@pragma("vm:entry-point")
getUint8List() => uint8List;
@pragma("vm:entry-point")
@@ -441,6 +444,38 @@
expect(result.associations, isEmpty);
},
+ // A built-in Set.
+ (VmService service, IsolateRef isolateRef) async {
+ final isolateId = isolateRef.id!;
+ final isolate = await service.getIsolate(isolateId);
+ // Call eval to get a Dart set.
+ final evalResult = await service
+ .invoke(isolateId, isolate.rootLib!.id!, 'getSet', []) as InstanceRef;
+ final objectId = evalResult.id!;
+ final result = await service.getObject(isolateId, objectId) as Instance;
+ expect(result.kind, InstanceKind.kSet);
+ expect(result.json!['_vmType'], equals('LinkedHashSet'));
+ expect(result.id, startsWith('objects/'));
+ expect(result.valueAsString, isNull);
+ expect(result.classRef!.name, equals('_InternalLinkedHashSet'));
+ expect(result.size, isPositive);
+ expect(result.fields, isEmpty);
+ expect(result.length, equals(3));
+ expect(result.offset, isNull);
+ expect(result.count, isNull);
+ final elements = result.elements!;
+ expect(elements.length, equals(3));
+ expect(elements[0] is InstanceRef, true);
+ expect(elements[0].kind, InstanceKind.kInt);
+ expect(elements[0].valueAsString, equals('6'));
+ expect(elements[1] is InstanceRef, true);
+ expect(elements[1].kind, InstanceKind.kInt);
+ expect(elements[1].valueAsString, equals('7'));
+ expect(elements[2] is InstanceRef, true);
+ expect(elements[2].kind, InstanceKind.kInt);
+ expect(elements[2].valueAsString, equals('8'));
+ },
+
// Uint8List.
(VmService service, IsolateRef isolateRef) async {
final isolateId = isolateRef.id!;
diff --git a/runtime/observatory/lib/src/elements/instance_ref.dart b/runtime/observatory/lib/src/elements/instance_ref.dart
index 01ba033..9cc74a6 100644
--- a/runtime/observatory/lib/src/elements/instance_ref.dart
+++ b/runtime/observatory/lib/src/elements/instance_ref.dart
@@ -171,6 +171,7 @@
];
case M.InstanceKind.list:
case M.InstanceKind.map:
+ case M.InstanceKind.set:
case M.InstanceKind.uint8ClampedList:
case M.InstanceKind.uint8List:
case M.InstanceKind.uint16List:
@@ -219,6 +220,7 @@
return true;
case M.InstanceKind.list:
case M.InstanceKind.map:
+ case M.InstanceKind.set:
case M.InstanceKind.uint8ClampedList:
case M.InstanceKind.uint8List:
case M.InstanceKind.uint16List:
@@ -297,6 +299,14 @@
])
.toList()
..addAll(_createShowMoreButton());
+ case M.InstanceKind.set:
+ return _loadedInstance!.elements!
+ .map<Element>((element) => new DivElement()
+ ..children = <Element>[
+ anyRef(_isolate, element, _objects, queue: _r.queue)
+ ])
+ .toList()
+ ..addAll(_createShowMoreButton());
case M.InstanceKind.uint8ClampedList:
case M.InstanceKind.uint8List:
case M.InstanceKind.uint16List:
diff --git a/runtime/observatory/lib/src/models/objects/instance.dart b/runtime/observatory/lib/src/models/objects/instance.dart
index 1b2d58e..5c0a344 100644
--- a/runtime/observatory/lib/src/models/objects/instance.dart
+++ b/runtime/observatory/lib/src/models/objects/instance.dart
@@ -31,6 +31,10 @@
/// Maps will be PlainInstance.
map,
+ /// An instance of the built-in VM Set implementation. User-defined
+ /// Sets will be PlainInstance.
+ set,
+
/// Vector instance kinds.
float32x4,
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 5815ca6..b0c17f1 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -152,6 +152,7 @@
bool get isInt => false;
bool get isList => false;
bool get isMap => false;
+ bool get isSet => false;
bool get isTypedData => false;
bool get isRegExp => false;
bool get isMirrorReference => false;
@@ -2737,6 +2738,8 @@
return M.InstanceKind.list;
case 'Map':
return M.InstanceKind.map;
+ case 'Set':
+ return M.InstanceKind.set;
case 'Float32x4':
return M.InstanceKind.float32x4;
case 'Float64x2':
@@ -2890,6 +2893,7 @@
bool get isInt => kind == M.InstanceKind.int;
bool get isList => kind == M.InstanceKind.list;
bool get isMap => kind == M.InstanceKind.map;
+ bool get isSet => kind == M.InstanceKind.set;
bool get isTypedData => M.isTypedData(kind);
bool get isSimdValue => M.isSimdValue(kind);
bool get isRegExp => kind == M.InstanceKind.regExp;
diff --git a/runtime/observatory/tests/service/get_object_rpc_test.dart b/runtime/observatory/tests/service/get_object_rpc_test.dart
index 774c855..6749c5a 100644
--- a/runtime/observatory/tests/service/get_object_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_object_rpc_test.dart
@@ -49,6 +49,9 @@
getMap() => {"x": 3, "y": 4, "z": 5};
@pragma("vm:entry-point")
+getSet() => {6, 7, 8};
+
+@pragma("vm:entry-point")
getUint8List() => uint8List;
@pragma("vm:entry-point")
@@ -462,6 +465,38 @@
expect(result['associations'], isEmpty);
},
+ // A built-in Set.
+ (Isolate isolate) async {
+ // Call eval to get a Dart set.
+ var evalResult = await invoke(isolate, 'getSet');
+ var params = {
+ 'objectId': evalResult['id'],
+ };
+ var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+ expect(result['type'], equals('Instance'));
+ expect(result['kind'], equals('Set'));
+ expect(result['_vmType'], equals('LinkedHashSet'));
+ expect(result['id'], startsWith('objects/'));
+ expect(result['valueAsString'], isNull);
+ expect(result['class']['type'], equals('@Class'));
+ expect(result['class']['name'], equals('_InternalLinkedHashSet'));
+ expect(result['size'], isPositive);
+ expect(result['fields'], isEmpty);
+ expect(result['length'], equals(3));
+ expect(result['offset'], isNull);
+ expect(result['count'], isNull);
+ expect(result['elements'].length, equals(3));
+ expect(result['elements'][0]['type'], equals('@Instance'));
+ expect(result['elements'][0]['kind'], equals('Int'));
+ expect(result['elements'][0]['valueAsString'], equals('6'));
+ expect(result['elements'][1]['type'], equals('@Instance'));
+ expect(result['elements'][1]['kind'], equals('Int'));
+ expect(result['elements'][1]['valueAsString'], equals('7'));
+ expect(result['elements'][2]['type'], equals('@Instance'));
+ expect(result['elements'][2]['kind'], equals('Int'));
+ expect(result['elements'][2]['valueAsString'], equals('8'));
+ },
+
// Uint8List.
(Isolate isolate) async {
// Call eval to get a Dart list.
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 41fe377..351000d 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
final result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], 'Version');
expect(result['major'], 3);
- expect(result['minor'], 61);
+ expect(result['minor'], 62);
expect(result['_privateMajor'], 0);
expect(result['_privateMinor'], 0);
},
diff --git a/runtime/observatory_2/lib/src/elements/instance_ref.dart b/runtime/observatory_2/lib/src/elements/instance_ref.dart
index e98148e..d63a023 100644
--- a/runtime/observatory_2/lib/src/elements/instance_ref.dart
+++ b/runtime/observatory_2/lib/src/elements/instance_ref.dart
@@ -169,6 +169,7 @@
];
case M.InstanceKind.list:
case M.InstanceKind.map:
+ case M.InstanceKind.set:
case M.InstanceKind.uint8ClampedList:
case M.InstanceKind.uint8List:
case M.InstanceKind.uint16List:
@@ -217,6 +218,7 @@
return true;
case M.InstanceKind.list:
case M.InstanceKind.map:
+ case M.InstanceKind.set:
case M.InstanceKind.uint8ClampedList:
case M.InstanceKind.uint8List:
case M.InstanceKind.uint16List:
@@ -295,6 +297,14 @@
])
.toList()
..addAll(_createShowMoreButton());
+ case M.InstanceKind.set:
+ return _loadedInstance.elements
+ .map<Element>((element) => new DivElement()
+ ..children = <Element>[
+ anyRef(_isolate, element, _objects, queue: _r.queue)
+ ])
+ .toList()
+ ..addAll(_createShowMoreButton());
case M.InstanceKind.uint8ClampedList:
case M.InstanceKind.uint8List:
case M.InstanceKind.uint16List:
diff --git a/runtime/observatory_2/lib/src/models/objects/instance.dart b/runtime/observatory_2/lib/src/models/objects/instance.dart
index ff914bc..3053bcb2 100644
--- a/runtime/observatory_2/lib/src/models/objects/instance.dart
+++ b/runtime/observatory_2/lib/src/models/objects/instance.dart
@@ -31,6 +31,10 @@
/// Maps will be PlainInstance.
map,
+ /// An instance of the built-in VM Set implementation. User-defined
+ /// Sets will be PlainInstance.
+ set,
+
/// Vector instance kinds.
float32x4,
diff --git a/runtime/observatory_2/lib/src/service/object.dart b/runtime/observatory_2/lib/src/service/object.dart
index bfe5b05..2cd8e66 100644
--- a/runtime/observatory_2/lib/src/service/object.dart
+++ b/runtime/observatory_2/lib/src/service/object.dart
@@ -152,6 +152,7 @@
bool get isInt => false;
bool get isList => false;
bool get isMap => false;
+ bool get isSet => false;
bool get isTypedData => false;
bool get isRegExp => false;
bool get isMirrorReference => false;
@@ -2746,6 +2747,8 @@
return M.InstanceKind.list;
case 'Map':
return M.InstanceKind.map;
+ case 'Set':
+ return M.InstanceKind.set;
case 'Float32x4':
return M.InstanceKind.float32x4;
case 'Float64x2':
@@ -2899,6 +2902,7 @@
bool get isInt => kind == M.InstanceKind.int;
bool get isList => kind == M.InstanceKind.list;
bool get isMap => kind == M.InstanceKind.map;
+ bool get isSet => kind == M.InstanceKind.set;
bool get isTypedData {
return M.isTypedData(kind);
}
diff --git a/runtime/observatory_2/tests/service_2/get_object_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_object_rpc_test.dart
index 20c65ff..d2094b5 100644
--- a/runtime/observatory_2/tests/service_2/get_object_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_object_rpc_test.dart
@@ -47,6 +47,9 @@
getMap() => {"x": 3, "y": 4, "z": 5};
@pragma("vm:entry-point")
+getSet() => {6, 7, 8};
+
+@pragma("vm:entry-point")
getUint8List() => uint8List;
@pragma("vm:entry-point")
@@ -460,6 +463,38 @@
expect(result['associations'], isEmpty);
},
+ // A built-in Set.
+ (Isolate isolate) async {
+ // Call eval to get a Dart set.
+ var evalResult = await invoke(isolate, 'getSet');
+ var params = {
+ 'objectId': evalResult['id'],
+ };
+ var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+ expect(result['type'], equals('Instance'));
+ expect(result['kind'], equals('Set'));
+ expect(result['_vmType'], equals('LinkedHashSet'));
+ expect(result['id'], startsWith('objects/'));
+ expect(result['valueAsString'], isNull);
+ expect(result['class']['type'], equals('@Class'));
+ expect(result['class']['name'], equals('_InternalLinkedHashSet'));
+ expect(result['size'], isPositive);
+ expect(result['fields'], isEmpty);
+ expect(result['length'], equals(3));
+ expect(result['offset'], isNull);
+ expect(result['count'], isNull);
+ expect(result['elements'].length, equals(3));
+ expect(result['elements'][0]['type'], equals('@Instance'));
+ expect(result['elements'][0]['kind'], equals('Int'));
+ expect(result['elements'][0]['valueAsString'], equals('6'));
+ expect(result['elements'][1]['type'], equals('@Instance'));
+ expect(result['elements'][1]['kind'], equals('Int'));
+ expect(result['elements'][1]['valueAsString'], equals('7'));
+ expect(result['elements'][2]['type'], equals('@Instance'));
+ expect(result['elements'][2]['kind'], equals('Int'));
+ expect(result['elements'][2]['valueAsString'], equals('8'));
+ },
+
// Uint8List.
(Isolate isolate) async {
// Call eval to get a Dart list.
diff --git a/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
index 7704093..6f53fb7 100644
--- a/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
final result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], equals('Version'));
expect(result['major'], equals(3));
- expect(result['minor'], equals(61));
+ expect(result['minor'], equals(62));
expect(result['_privateMajor'], equals(0));
expect(result['_privateMinor'], equals(0));
},
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 79b826e..6f4a272 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -1455,7 +1455,7 @@
void LinkedHashSet::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
- jsobj.AddProperty("kind", "PlainInstance");
+ jsobj.AddProperty("kind", "Set");
jsobj.AddProperty("length", Length());
if (ref) {
return;
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 0ffb69e..b596e14 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -17,7 +17,7 @@
namespace dart {
#define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 61
+#define SERVICE_PROTOCOL_MINOR_VERSION 62
class Array;
class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 8525ff0..be92fa4 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -962,7 +962,7 @@
collected, then an [Object](#object) will be returned.
The _offset_ and _count_ parameters are used to request subranges of
-Instance objects with the kinds: String, List, Map, Uint8ClampedList,
+Instance objects with the kinds: String, List, Map, Set, Uint8ClampedList,
Uint8List, Uint16List, Uint32List, Uint64List, Int8List, Int16List,
Int32List, Int64List, Flooat32List, Float64List, Inst32x3List,
Float32x4List, and Float64x2List. These parameters are otherwise
@@ -2698,6 +2698,7 @@
// String
// List
// Map
+ // Set
// Uint8ClampedList
// Uint8List
// Uint16List
@@ -2828,6 +2829,7 @@
// String
// List
// Map
+ // Set
// Uint8ClampedList
// Uint8List
// Uint16List
@@ -2874,6 +2876,7 @@
// String
// List
// Map
+ // Set
// Uint8ClampedList
// Uint8List
// Uint16List
@@ -2929,10 +2932,11 @@
// The fields of this Instance.
BoundField[] fields [optional];
- // The elements of a List instance.
+ // The elements of a List or Set instance.
//
// Provided for instance kinds:
// List
+ // Set
(@Instance|Sentinel)[] elements [optional];
// The elements of a Map instance.
@@ -3096,6 +3100,10 @@
// Maps will be PlainInstance.
Map,
+ // An instance of the built-in VM Set implementation. User-defined
+ // Sets will be PlainInstance.
+ Set,
+
// Vector instance kinds.
Float32x4,
Float64x2,
@@ -4396,5 +4404,6 @@
3.59 | Added `abstract` property to `@Function` and `Function`.
3.60 | Added `gcType` property to `Event`.
3.61 | Added `isolateGroupId` property to `@Isolate` and `Isolate`.
+3.62 | Added `Set` to `InstanceKind`.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss