Skip to content

Commit fe5b975

Browse files
author
Anna Gringauze
authored
Hide internal implementation details in type objects (#2103)
* Simplify class metadata * Cleanup * update changelog ref * Cleanup * Hide internal details in type presentation * update ref in changelod * Fix tests * Fix inadvertent changes * Return InstanceKind.kType instances for type objects to match VM * Addressed CR comments * Addressed CR comments * Inline type wrapper handling to minimize calls to wrapType * Address CR comments
1 parent 12f2285 commit fe5b975

23 files changed

+1196
-691
lines changed

dwds/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- Do not show async frame errors on evaluation. - [#2073](https://github.com/dart-lang/webdev/pull/2073)
44
- Refactor code for presenting record instances. - [#2074](https://github.com/dart-lang/webdev/pull/2074)
55
- Display record types concisely. - [#2070](https://github.com/dart-lang/webdev/pull/2070)
6+
- Display type objects concisely. - [#2103](https://github.com/dart-lang/webdev/pull/2103)
67

78
## 19.0.0
89

dwds/lib/src/debugging/classes.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,11 @@ class ClassHelper extends Domain {
199199
fieldDescriptors.forEach((name, descriptor) {
200200
final classMetaData = ClassMetaData(
201201
jsName: descriptor['classRefName'],
202-
libraryId: descriptor['classRefLibraryId'],
203-
dartName: descriptor['classRefDartName'],
202+
runtimeKind: RuntimeObjectKind.type,
203+
classRef: classRefFor(
204+
descriptor['classRefLibraryId'],
205+
descriptor['classRefDartName'],
206+
),
204207
);
205208
fieldRefs.add(
206209
FieldRef(
@@ -209,8 +212,7 @@ class ClassHelper extends Domain {
209212
declaredType: InstanceRef(
210213
identityHashCode: createId().hashCode,
211214
id: createId(),
212-
kind: InstanceKind.kType,
213-
// TODO(elliette): Is this the same as classRef?
215+
kind: classMetaData.kind,
214216
classRef: classMetaData.classRef,
215217
),
216218
isConst: descriptor['isConst'] as bool,

dwds/lib/src/debugging/dart_scope.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'package:dwds/src/debugging/debugger.dart';
5+
import 'package:dwds/src/utilities/domain.dart';
66
import 'package:dwds/src/utilities/objects.dart';
77
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
88

@@ -25,7 +25,7 @@ final previousDdcTemporaryVariableRegExp =
2525
///
2626
/// See chromedevtools.github.io/devtools-protocol/tot/Debugger#type-CallFrame.
2727
Future<List<Property>> visibleProperties({
28-
required Debugger debugger,
28+
required AppInspectorInterface inspector,
2929
required WipCallFrame frame,
3030
}) async {
3131
final allProperties = <Property>[];
@@ -48,7 +48,7 @@ Future<List<Property>> visibleProperties({
4848
for (var scope in filterScopes(frame).reversed) {
4949
final objectId = scope.object.objectId;
5050
if (objectId != null) {
51-
final properties = await debugger.getProperties(objectId);
51+
final properties = await inspector.getProperties(objectId);
5252
allProperties.addAll(properties);
5353
}
5454
}

dwds/lib/src/debugging/debugger.dart

Lines changed: 4 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,14 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:async';
6-
import 'dart:math' as math;
76

87
import 'package:dwds/src/debugging/dart_scope.dart';
98
import 'package:dwds/src/debugging/frame_computer.dart';
109
import 'package:dwds/src/debugging/location.dart';
11-
import 'package:dwds/src/debugging/metadata/class.dart';
1210
import 'package:dwds/src/debugging/remote_debugger.dart';
1311
import 'package:dwds/src/debugging/skip_list.dart';
1412
import 'package:dwds/src/loaders/strategy.dart';
1513
import 'package:dwds/src/services/chrome_debug_exception.dart';
16-
import 'package:dwds/src/utilities/conversions.dart';
1714
import 'package:dwds/src/utilities/dart_uri.dart';
1815
import 'package:dwds/src/utilities/domain.dart';
1916
import 'package:dwds/src/utilities/objects.dart' show Property;
@@ -394,15 +391,16 @@ class Debugger extends Domain {
394391
/// The variables visible in a frame in Dart protocol [BoundVariable] form.
395392
Future<List<BoundVariable>> variablesFor(WipCallFrame frame) async {
396393
// TODO(alanknight): Can these be moved to dart_scope.dart?
397-
final properties = await visibleProperties(debugger: this, frame: frame);
394+
final properties =
395+
await visibleProperties(inspector: inspector, frame: frame);
398396
final boundVariables = await Future.wait(
399397
properties.map(_boundVariable),
400398
);
401399

402400
// Filter out variables that do not come from dart code, such as native
403401
// JavaScript objects
404402
return boundVariables
405-
.where((bv) => isDisplayableObject(bv?.value))
403+
.where((bv) => inspector.isDisplayableObject(bv?.value))
406404
.toList()
407405
.cast();
408406
}
@@ -432,84 +430,6 @@ class Debugger extends Domain {
432430
return null;
433431
}
434432

435-
static bool _isEmptyRange({
436-
required int length,
437-
int? offset,
438-
int? count,
439-
}) {
440-
if (count == 0) return true;
441-
if (offset == null) return false;
442-
return offset >= length;
443-
}
444-
445-
static bool _isSubRange({
446-
int? offset,
447-
int? count,
448-
}) {
449-
if (offset == 0 && count == null) return false;
450-
return offset != null || count != null;
451-
}
452-
453-
/// Compute the last possible element index in the range of [offset]..end
454-
/// that includes [count] elements, if available.
455-
static int? _calculateRangeEnd({
456-
int? count,
457-
required int offset,
458-
required int length,
459-
}) =>
460-
count == null ? null : math.min(offset + count, length);
461-
462-
/// Calculate the number of available elements in the range.
463-
static int _calculateRangeCount({
464-
int? count,
465-
required int offset,
466-
required int length,
467-
}) =>
468-
count == null ? length - offset : math.min(count, length - offset);
469-
470-
/// Find a sub-range of the entries for a Map/List when offset and/or count
471-
/// have been specified on a getObject request.
472-
///
473-
/// If the object referenced by [id] is not a system List or Map then this
474-
/// will just return a RemoteObject for it and ignore [offset], [count] and
475-
/// [length]. If it is, then [length] should be the number of entries in the
476-
/// List/Map and [offset] and [count] should indicate the desired range.
477-
Future<RemoteObject> _subRange(
478-
String id, {
479-
required int offset,
480-
int? count,
481-
required int length,
482-
}) async {
483-
// TODO(#809): Sometimes we already know the type of the object, and
484-
// we could take advantage of that to short-circuit.
485-
final receiver = remoteObjectFor(id);
486-
final end =
487-
_calculateRangeEnd(count: count, offset: offset, length: length);
488-
final rangeCount =
489-
_calculateRangeCount(count: count, offset: offset, length: length);
490-
final args =
491-
[offset, rangeCount, end].map(dartIdFor).map(remoteObjectFor).toList();
492-
// If this is a List, just call sublist. If it's a Map, get the entries, but
493-
// avoid doing a toList on a large map using skip/take to get the section we
494-
// want. To make those alternatives easier in JS, pass both count and end.
495-
final expression = '''
496-
function (offset, count, end) {
497-
const sdk = ${globalLoadStrategy.loadModuleSnippet}("dart_sdk");
498-
if (sdk.core.Map.is(this)) {
499-
const entries = sdk.dart.dload(this, "entries");
500-
const skipped = sdk.dart.dsend(entries, "skip", [offset])
501-
const taken = sdk.dart.dsend(skipped, "take", [count]);
502-
return sdk.dart.dsend(taken, "toList", []);
503-
} else if (sdk.core.List.is(this)) {
504-
return sdk.dart.dsendRepl(this, "sublist", [offset, end]);
505-
} else {
506-
return this;
507-
}
508-
}
509-
''';
510-
return await inspector.jsCallFunctionOn(receiver, expression, args);
511-
}
512-
513433
// TODO(elliette): https://github.com/dart-lang/webdev/issues/1501 Re-enable
514434
// after checking with Chrome team if there is a way to check if the Chrome
515435
// DevTools is showing an overlay. Both cannot be shown at the same time:
@@ -533,48 +453,6 @@ class Debugger extends Domain {
533453
// _pausedOverlayVisible = false;
534454
// }
535455

536-
/// Calls the Chrome Runtime.getProperties API for the object with [objectId].
537-
///
538-
/// Note that the property names are JS names, e.g.
539-
/// Symbol(DartClass.actualName) and will need to be converted. For a system
540-
/// List or Map, [offset] and/or [count] can be provided to indicate a desired
541-
/// range of entries. They will be ignored if there is no [length].
542-
Future<List<Property>> getProperties(
543-
String objectId, {
544-
int? offset,
545-
int? count,
546-
int? length,
547-
}) async {
548-
String rangeId = objectId;
549-
// Ignore offset/count if there is no length:
550-
if (length != null) {
551-
if (_isEmptyRange(offset: offset, count: count, length: length)) {
552-
return [];
553-
}
554-
if (_isSubRange(offset: offset, count: count)) {
555-
final range = await _subRange(
556-
objectId,
557-
offset: offset ?? 0,
558-
count: count,
559-
length: length,
560-
);
561-
rangeId = range.objectId ?? rangeId;
562-
}
563-
}
564-
final jsProperties = await sendCommandAndValidateResult<List>(
565-
_remoteDebugger,
566-
method: 'Runtime.getProperties',
567-
resultField: 'result',
568-
params: {
569-
'objectId': rangeId,
570-
'ownProperties': true,
571-
},
572-
);
573-
return jsProperties
574-
.map<Property>((each) => Property(each as Map<String, dynamic>))
575-
.toList();
576-
}
577-
578456
/// Returns a Dart [Frame] for a JS [frame].
579457
Future<Frame?> calculateDartFrameFor(
580458
WipCallFrame frame,
@@ -658,7 +536,7 @@ class Debugger extends Domain {
658536
if (map['type'] == 'object') {
659537
final obj = RemoteObject(map);
660538
exception = await inspector.instanceRefFor(obj);
661-
if (exception != null && isNativeJsError(exception)) {
539+
if (exception != null && inspector.isNativeJsError(exception)) {
662540
if (obj.description != null) {
663541
// Create a string exception object.
664542
final description =
@@ -845,23 +723,6 @@ Future<T> sendCommandAndValidateResult<T>(
845723
return result;
846724
}
847725

848-
/// Returns true for objects we display for the user.
849-
bool isDisplayableObject(Object? object) =>
850-
object is Sentinel ||
851-
object is InstanceRef &&
852-
!isNativeJsObject(object) &&
853-
!isNativeJsError(object);
854-
855-
/// Returns true for non-dart JavaScript objects.
856-
bool isNativeJsObject(InstanceRef instanceRef) {
857-
return isNativeJsObjectRef(instanceRef.classRef);
858-
}
859-
860-
/// Returns true of JavaScript exceptions.
861-
bool isNativeJsError(InstanceRef instanceRef) {
862-
return instanceRef.classRef == classRefForNativeJsError;
863-
}
864-
865726
/// Returns the Dart line number for the provided breakpoint.
866727
int _lineNumberFor(Breakpoint breakpoint) =>
867728
int.parse(breakpoint.id!.split('#').last.split(':').first);

0 commit comments

Comments
 (0)