Skip to content

Commit 6b474e0

Browse files
srujzsCommit Queue
authored andcommitted
[dart:js_interop] Update jsify and dartify docs to be more accurate
#55222 It is quite confusing what these methods do or are supposed to do. While we want to update the implementation, we should instruct users what to expect for now. CoreLibraryReviewExempt: Doc-only change. Change-Id: I9b49d135f7c252659d2c52a0fb314a37251a9ac9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425186 Commit-Queue: Srujan Gaddam <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent 5766681 commit 6b474e0

File tree

3 files changed

+57
-12
lines changed

3 files changed

+57
-12
lines changed

sdk/lib/_internal/wasm/lib/js_helper.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,11 +320,18 @@ WasmExternRef? jsifyRaw(Object? o) {
320320
if (o is js_types.JSDataViewImpl) return jsifyJSDataViewImpl(o);
321321
if (o is ByteData) return jsifyByteData(o);
322322
} else if (o is List<Object?>) {
323+
// TODO(srujzs): Once `package:js` support is fully removed, we should
324+
// remove this as it'll be dead code. `jsify` will convert iterables
325+
// differently, and `dart:js_interop` `external` conversions shouldn't come
326+
// across this code.
323327
return _jsifyRawList(o);
324328
} else if (o is ByteBuffer) {
325329
if (o is js_types.JSArrayBufferImpl) return jsifyJSArrayBufferImpl(o);
326330
return jsArrayBufferFromDartByteBuffer(o);
327331
} else if (o is Function) {
332+
// TODO(srujzs): Once `package:js` support is fully removed, we should
333+
// remove this to unify with the JS backends, which don't do this
334+
// conversion.
328335
return jsifyFunction(o);
329336
} else {
330337
return jsObjectFromDartObject(o);

sdk/lib/_internal/wasm/lib/js_util_patch.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ Object? dartify(Object? object) {
219219
if (o is! JSValue) return o;
220220
WasmExternRef? ref = o.toExternRef;
221221
final refType = externRefType(ref);
222-
// TODO(joshualitt) handle Date and Promise.
222+
// TODO(srujzs): Either handle Date and Promise, or remove them completely
223+
// from the conversion (preferred) across all backends.
223224
if (refType == ExternRefType.unknown && isJSSimpleObject(ref)) {
224225
final dartMap = <Object?, Object?>{};
225226
convertedObjects[o] = dartMap;

sdk/lib/js_interop/js_interop.dart

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -572,34 +572,71 @@ extension JSAnyUtilityExtension on JSAny? {
572572
@Since('3.4')
573573
external bool isA<T extends JSAny?>();
574574

575-
/// Converts a JavaScript value to the Dart equivalent if possible.
575+
/// Converts a JavaScript JSON-like value to the Dart equivalent if possible.
576576
///
577577
/// Effectively the inverse of [NullableObjectUtilExtension.jsify], [dartify]
578-
/// takes a JavaScript value and recursively converts it to a Dart object.
579-
/// Only JavaScript primitives, `Array`s, typed arrays, and map-like objects
580-
/// with string property names are supported.
578+
/// takes a JavaScript JSON-like value and recursively converts it to a Dart
579+
/// object, doing the following:
580+
///
581+
/// - If the value is a string, number, boolean, `null`, `undefined`,
582+
/// `DataView` or a typed array, does the equivalent `toDart` operation if
583+
/// it exists and returns the result.
584+
/// - If the value is a simple JS object (the protoype is either `null` or JS
585+
/// `Object`), creates and returns a `[Map]<Object?, Object?>` whose keys
586+
/// are the recursively converted keys obtained from `Object.keys` and its
587+
/// values are the associated values of the keys in the JS object.
588+
/// - If the value is a JS `Array`, each item in it is recursively converted
589+
/// and added to a new `[List]<Object?>`, which is then returned.
590+
/// - Otherwise, the conversion is undefined.
591+
///
592+
/// If the value contains a cycle, the behavior is undefined.
581593
///
582594
/// > [!NOTE]
583595
/// > Prefer using the specific conversion method like `toDart` if you know
584-
/// > the JavaScript type as this method may perform many type-checks.
596+
/// > the JavaScript type as this method may perform many type-checks. You
597+
/// > should generally call this method with values that only contain
598+
/// > JSON-like values as the conversion may be platform- and
599+
/// > compiler-specific otherwise.
585600
// TODO(srujzs): We likely need stronger tests for this method to ensure
586-
// consistency.
601+
// consistency. We should also limit the accepted types in this API to avoid
602+
// confusion. Once the conversion for unrelated types is consistent across all
603+
// backends, we can update the documentation to say that the value is
604+
// internalized instead of the conversion being undefined.
587605
external Object? dartify();
588606
}
589607

590608
/// Common utility functions for <code>[Object]?</code>s.
591609
extension NullableObjectUtilExtension on Object? {
592-
/// Converts a Dart object to the JavaScript equivalent if possible.
610+
/// Converts a Dart JSON-like object to the JavaScript equivalent if possible.
593611
///
594612
/// Effectively the inverse of [JSAnyUtilityExtension.dartify], [jsify] takes
595-
/// a Dart object and recursively converts it to a JavaScript value. Only Dart
596-
/// primitives, [Iterable]s, typed lists, and [Map]s are supported.
613+
/// a Dart JSON-like object and recursively converts it to a JavaScript value,
614+
/// doing the following:
615+
///
616+
/// - If the object is a JS value, returns the object.
617+
/// - If the object is a Dart primitive type, `null`, or a `dart:typed_data`
618+
/// type, does the equivalent `toJS` operation if it exists and returns the
619+
/// result.
620+
/// - If the object is a [Map], creates and returns a new JS object whose
621+
/// properties and associated values are the recursively converted keys and
622+
/// values of the [Map].
623+
/// - If the object is an [Iterable], each item in it is recursively converted
624+
/// and pushed into a new JS `Array` which is then returned.
625+
/// - Otherwise, the conversion is undefined.
626+
///
627+
/// If the object contains a cycle, the behavior is undefined.
597628
///
598629
/// > [!NOTE]
599630
/// > Prefer using the specific conversion method like `toJS` if you know the
600-
/// > Dart type as this method may perform many type-checks.
631+
/// > Dart type as this method may perform many type-checks. You should
632+
/// > generally call this method with objects that only contain JSON-like
633+
/// > values as the conversion may be platform- and compiler-specific
634+
/// > otherwise.
601635
// TODO(srujzs): We likely need stronger tests for this method to ensure
602-
// consistency.
636+
// consistency. We should also limit the accepted types in this API to avoid
637+
// confusion. Once the conversion for unrelated types is consistent across all
638+
// backends, we can update the documentation to say that the object is
639+
// externalized instead of the conversion being undefined.
603640
external JSAny? jsify();
604641
}
605642

0 commit comments

Comments
 (0)