@@ -116,16 +116,15 @@ class InstanceHelper extends Domain {
116
116
return _closureInstanceFor (remoteObject);
117
117
}
118
118
119
- final properties = await debugger.getProperties (objectId,
120
- offset: offset, count: count, length: metaData.length);
121
119
if (metaData.isSystemList) {
122
- return await _listInstanceFor (
123
- classRef, remoteObject, properties, offset, count );
120
+ return await _listInstanceFor (classRef, remoteObject,
121
+ offset : offset, count : count, length : metaData.length );
124
122
} else if (metaData.isSystemMap) {
125
- return await _mapInstanceFor (
126
- classRef, remoteObject, properties, offset, count );
123
+ return await _mapInstanceFor (classRef, remoteObject,
124
+ offset : offset, count : count, length : metaData.length );
127
125
} else {
128
- return await _plainInstanceFor (classRef, remoteObject, properties);
126
+ return await _plainInstanceFor (classRef, remoteObject,
127
+ offset: offset, count: count, length: metaData.length);
129
128
}
130
129
}
131
130
@@ -171,10 +170,18 @@ class InstanceHelper extends Domain {
171
170
172
171
/// Create a plain instance of [classRef] from [remoteObject] and the JS
173
172
/// properties [properties] .
174
- Future <Instance ?> _plainInstanceFor (ClassRef classRef,
175
- RemoteObject remoteObject, List <Property > properties) async {
173
+ Future <Instance ?> _plainInstanceFor (
174
+ ClassRef classRef,
175
+ RemoteObject remoteObject, {
176
+ int ? offset,
177
+ int ? count,
178
+ int ? length,
179
+ }) async {
176
180
final objectId = remoteObject.objectId;
177
181
if (objectId == null ) return null ;
182
+
183
+ final properties = await debugger.getProperties (objectId,
184
+ offset: offset, count: count, length: length);
178
185
final dartProperties = await _dartFieldsFor (properties, remoteObject);
179
186
var boundFields = await Future .wait (
180
187
dartProperties.map <Future <BoundField >>((p) => _fieldFor (p, classRef)));
@@ -200,8 +207,8 @@ class InstanceHelper extends Domain {
200
207
}
201
208
202
209
/// The associations for a Dart Map or IdentityMap.
203
- Future <List <MapAssociation >> _mapAssociations (
204
- RemoteObject map, int ? offset, int ? count) async {
210
+ Future <List <MapAssociation >> _mapAssociations (RemoteObject map,
211
+ { int ? offset, int ? count} ) async {
205
212
// We do this in in awkward way because we want the keys and values, but we
206
213
// can't return things by value or some Dart objects will come back as
207
214
// values that we need to be RemoteObject, e.g. a List of int.
@@ -241,67 +248,95 @@ class InstanceHelper extends Domain {
241
248
242
249
/// Create a Map instance with class [classRef] from [remoteObject] .
243
250
Future <Instance ?> _mapInstanceFor (
244
- ClassRef classRef,
245
- RemoteObject remoteObject,
246
- List <Property > _,
247
- int ? offset,
248
- int ? count) async {
251
+ ClassRef classRef,
252
+ RemoteObject remoteObject, {
253
+ int ? offset,
254
+ int ? count,
255
+ int ? length,
256
+ }) async {
249
257
final objectId = remoteObject.objectId;
250
258
if (objectId == null ) return null ;
259
+
251
260
// Maps are complicated, do an eval to get keys and values.
252
- final associations = await _mapAssociations (remoteObject, offset, count);
253
- final length = (offset == null && count == null )
254
- ? associations.length
255
- : ( await instanceRefFor (remoteObject)) ? .length;
261
+ final associations =
262
+ await _mapAssociations (remoteObject, offset : offset, count: count);
263
+ final rangeCount = _calculateRangeCount (
264
+ count : count, elementCount : associations .length, length : length) ;
256
265
return Instance (
257
266
identityHashCode: remoteObject.objectId.hashCode,
258
267
kind: InstanceKind .kMap,
259
268
id: objectId,
260
269
classRef: classRef)
261
270
..length = length
262
271
..offset = offset
263
- ..count = (associations.length == length) ? null : associations.length
272
+ ..count = rangeCount
264
273
..associations = associations;
265
274
}
266
275
267
276
/// Create a List instance of [classRef] from [remoteObject] with the JS
268
277
/// properties [properties] .
269
278
Future <Instance ?> _listInstanceFor (
270
- ClassRef classRef,
271
- RemoteObject remoteObject,
272
- List <Property > properties,
273
- int ? offset,
274
- int ? count) async {
279
+ ClassRef classRef,
280
+ RemoteObject remoteObject, {
281
+ int ? offset,
282
+ int ? count,
283
+ int ? length,
284
+ }) async {
275
285
final objectId = remoteObject.objectId;
276
286
if (objectId == null ) return null ;
277
287
278
- /// TODO(annagrin): split into cases to make the logic clear.
279
- /// TODO(annagrin): make sure we use offset correctly.
280
- final numberOfProperties = _lengthOf (properties) ?? 0 ;
281
- final length = (offset == null && count == null )
282
- ? numberOfProperties
283
- : (await instanceRefFor (remoteObject))? .length;
284
- final indexed = properties.sublist (
285
- 0 , min (count ?? length ?? numberOfProperties, numberOfProperties));
286
- final fields = await Future .wait (indexed
287
- .map ((property) async => await _instanceRefForRemote (property.value)));
288
+ final elements = await _listElements (remoteObject,
289
+ offset: offset, count: count, length: length);
290
+ final rangeCount = _calculateRangeCount (
291
+ count: count, elementCount: elements.length, length: length);
288
292
return Instance (
289
293
identityHashCode: remoteObject.objectId.hashCode,
290
294
kind: InstanceKind .kList,
291
295
id: objectId,
292
296
classRef: classRef)
293
297
..length = length
294
- ..elements = fields
298
+ ..elements = elements
295
299
..offset = offset
296
- ..count = (numberOfProperties == length) ? null : numberOfProperties;
300
+ ..count = rangeCount;
301
+ }
302
+
303
+ /// The elements for a Dart List.
304
+ Future <List <InstanceRef ?>> _listElements (
305
+ RemoteObject list, {
306
+ int ? offset,
307
+ int ? count,
308
+ int ? length,
309
+ }) async {
310
+ final properties = await debugger.getProperties (list.objectId! ,
311
+ offset: offset, count: count, length: length);
312
+ final rangeCount = _calculateRangeCount (
313
+ count: count, elementCount: _lengthOf (properties), length: length);
314
+ final indexed = properties.sublist (0 , rangeCount);
315
+
316
+ return Future .wait (indexed
317
+ .map ((property) async => await _instanceRefForRemote (property.value)));
318
+ }
319
+
320
+ /// Return the available count of elements in the requested range.
321
+ /// Return `null` if the range includes the whole object.
322
+ /// [count] is the range length requested by the `getObject` call.
323
+ /// [elementCount] is the number of elements in the runtime object.
324
+ /// [length] is the expected length of the whole object, read from
325
+ /// the [ClassMetaData] .
326
+ static int ? _calculateRangeCount (
327
+ {int ? count, int ? elementCount, int ? length}) {
328
+ if (count == null ) return null ;
329
+ if (elementCount == null ) return null ;
330
+ if (length == elementCount) return null ;
331
+ return min (count, elementCount);
297
332
}
298
333
299
334
/// Return the value of the length attribute from [properties] , if present.
300
335
///
301
336
/// This is only applicable to Lists or Maps, where we expect a length
302
337
/// attribute. Even if a plain instance happens to have a length field, we
303
338
/// don't use it to determine the properties to display.
304
- int ? _lengthOf (List <Property > properties) {
339
+ static int ? _lengthOf (List <Property > properties) {
305
340
final lengthProperty = properties.firstWhere ((p) => p.name == 'length' );
306
341
return lengthProperty.value? .value as int ? ;
307
342
}
0 commit comments