Skip to content

Commit b8402f5

Browse files
srujzsCommit Queue
authored and
Commit Queue
committed
[dart:js_interop] Make ExternalDartReference generic
Closes #55342 Closes #55536 Closes #56015 - Adds a type parameter T that extends Object? to ExternalDartReference to capture the type of the value that was externalized. -- In the JS compilers, the representation type of ExternalDartReference is now T. -- In dart2wasm, the representation type is now JSValue?. - ExternalDartReference no longer implements Object. - Return type of toDartObject is now T. - ObjectToExternalDartReference and ExternalDartReferenceToObject both now are on a T that is bound to Object?. - Internal patches for WeakReference and Finalizer are updated. Change-Id: Ic2dc834b17ec6a4eb2122cba3c495a6e0a1eae6e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370663 Commit-Queue: Srujan Gaddam <[email protected]> Reviewed-by: Martin Kustermann <[email protected]> Reviewed-by: Sigmund Cherem <[email protected]> Reviewed-by: Lasse Nielsen <[email protected]>
1 parent 2653075 commit b8402f5

File tree

11 files changed

+303
-137
lines changed

11 files changed

+303
-137
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,18 @@
5757
of a `String` to support other JS values as well, like `TrustedScriptURL`s.
5858
- **Breaking Change** [#55267][]: `isTruthy` and `not` now return `JSBoolean`
5959
instead of `bool` to be consistent with the other operators.
60+
- **Breaking Change** `ExternalDartReference` no longer implements `Object`.
61+
`ExternalDartReference` now accepts a type parameter `T` with a bound of
62+
`Object?` to capture the type of the Dart object that is externalized.
63+
`ExternalDartReferenceToObject.toDartObject` now returns a `T`.
64+
`ExternalDartReferenceToObject` and `ObjectToExternalDartReference` are now
65+
extensions on `T` and `ExternalDartReference<T>`, respectively, where `T
66+
extends Object?`. See [#55342][] and [#55536][] for more details.
6067

6168
[#55508]: https://github.com/dart-lang/sdk/issues/55508
6269
[#55267]: https://github.com/dart-lang/sdk/issues/55267
70+
[#55342]: https://github.com/dart-lang/sdk/issues/55342
71+
[#55536]: https://github.com/dart-lang/sdk/issues/55536
6372

6473
### Tools
6574

pkg/dart2wasm/lib/js/callback_specializer.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class CallbackSpecializer {
3333
VariableGet v = VariableGet(positionalParameters[i]);
3434
if (_util.isJSValueType(callbackParameterType) && boxExternRef) {
3535
expression = _createJSValue(v);
36-
if (!callbackParameterType.isPotentiallyNullable) {
36+
if (!callbackParameterType.extensionTypeErasure.isPotentiallyNullable) {
3737
expression = NullCheck(expression);
3838
}
3939
} else {

pkg/dart2wasm/lib/js/util.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class CoreTypesUtil {
7070
Procedure jsifyTarget(DartType type) =>
7171
isJSValueType(type) ? jsValueUnboxTarget : jsifyRawTarget;
7272

73-
/// Return whether [type] erases to a `JSValue`.
73+
/// Whether [type] erases to a `JSValue` or `JSValue?`.
7474
bool isJSValueType(DartType type) =>
7575
_extensionIndex.isStaticInteropType(type) ||
7676
_extensionIndex.isExternalDartReferenceType(type);
@@ -112,7 +112,7 @@ class CoreTypesUtil {
112112
// there are static interop types that are not boxed as JSValue, we
113113
// might need a proper cast then.
114114
expression = invokeOneArg(jsValueBoxTarget, invocation);
115-
if (returnType.isPotentiallyNonNullable) {
115+
if (returnType.extensionTypeErasure.isPotentiallyNonNullable) {
116116
expression = NullCheck(expression);
117117
}
118118
} else {

sdk/lib/_internal/js_shared/lib/js_interop_patch.dart

+52-32
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ JSObjectRepType _createObjectLiteral() =>
1919
@pragma('dart2js:prefer-inline')
2020
JSObject get globalContext => staticInteropGlobalContext as JSObject;
2121

22-
/// Helper for working with the [JSAny?] top type in a backend agnostic way.
22+
// Helper for working with the JSAny? top type in a backend agnostic way.
2323
@patch
2424
extension NullableUndefineableJSAnyExtension on JSAny? {
2525
@patch
@@ -53,15 +53,16 @@ extension JSAnyUtilityExtension on JSAny? {
5353
Object? dartify() => js_util.dartify(this);
5454
}
5555

56-
/// Utility extensions for [Object?].
56+
// Utility extensions for Object?.
5757
@patch
5858
extension NullableObjectUtilExtension on Object? {
5959
@patch
6060
@pragma('dart2js:prefer-inline')
6161
JSAny? jsify() => js_util.jsify(this);
6262
}
6363

64-
/// [JSExportedDartFunction] <-> [Function]
64+
// -----------------------------------------------------------------------------
65+
// JSExportedDartFunction <-> Function
6566
@patch
6667
extension JSExportedDartFunctionToFunction on JSExportedDartFunction {
6768
// TODO(srujzs): We should unwrap rather than allow arbitrary JS functions
@@ -79,15 +80,16 @@ extension FunctionToJSExportedDartFunction on Function {
7980
js_util.allowInterop(this) as JSExportedDartFunction;
8081
}
8182

82-
/// Embedded global property for wrapped Dart objects passed via JS interop.
83-
///
84-
/// This is a Symbol so that different Dart applications don't share Dart
85-
/// objects from different Dart runtimes. We expect all [JSBoxedDartObject]s to
86-
/// have this Symbol.
83+
// Embedded global property for wrapped Dart objects passed via JS interop.
84+
//
85+
// This is a Symbol so that different Dart applications don't share Dart
86+
// objects from different Dart runtimes. We expect all JSBoxedDartObjects to
87+
// have this Symbol.
8788
final Object _jsBoxedDartObjectProperty =
8889
foreign_helper.JS('', 'Symbol("jsBoxedDartObjectProperty")');
8990

90-
/// [JSBoxedDartObject] <-> [Object]
91+
// -----------------------------------------------------------------------------
92+
// JSBoxedDartObject <-> Object
9193
@patch
9294
extension JSBoxedDartObjectToObject on JSBoxedDartObject {
9395
@patch
@@ -118,31 +120,34 @@ extension ObjectToJSBoxedDartObject on Object {
118120
}
119121
}
120122

121-
/// [ExternalDartReference] <-> [Object]
123+
// -----------------------------------------------------------------------------
124+
// ExternalDartReference <-> T
122125
@patch
123-
extension ExternalDartReferenceToObject on ExternalDartReference {
126+
extension ExternalDartReferenceToObject<T extends Object?>
127+
on ExternalDartReference<T> {
124128
@patch
125129
@pragma('dart2js:prefer-inline')
126-
Object get toDartObject => this;
130+
T get toDartObject => _externalDartReference;
127131
}
128132

129133
@patch
130-
extension ObjectToExternalDartReference on Object {
134+
extension ObjectToExternalDartReference<T extends Object?> on T {
131135
@patch
132136
@pragma('dart2js:prefer-inline')
133-
ExternalDartReference get toExternalReference =>
134-
ExternalDartReference._(this);
137+
ExternalDartReference<T> get toExternalReference =>
138+
ExternalDartReference<T>._(this);
135139
}
136140

137-
/// [JSPromise] -> [Future].
141+
// JSPromise -> Future
138142
@patch
139143
extension JSPromiseToFuture<T extends JSAny?> on JSPromise<T> {
140144
@patch
141145
@pragma('dart2js:prefer-inline')
142146
Future<T> get toDart => js_util.promiseToFuture<T>(this);
143147
}
144148

145-
/// [JSArrayBuffer] <-> [ByteBuffer]
149+
// -----------------------------------------------------------------------------
150+
// JSArrayBuffer <-> ByteBuffer
146151
@patch
147152
extension JSArrayBufferToByteBuffer on JSArrayBuffer {
148153
@patch
@@ -157,7 +162,8 @@ extension ByteBufferToJSArrayBuffer on ByteBuffer {
157162
JSArrayBuffer get toJS => this as JSArrayBuffer;
158163
}
159164

160-
/// [JSDataView] <-> [ByteData]
165+
// -----------------------------------------------------------------------------
166+
// JSDataView <-> ByteData
161167
@patch
162168
extension JSDataViewToByteData on JSDataView {
163169
@patch
@@ -172,7 +178,8 @@ extension ByteDataToJSDataView on ByteData {
172178
JSDataView get toJS => this as JSDataView;
173179
}
174180

175-
/// [JSInt8Array] <-> [Int8List]
181+
// -----------------------------------------------------------------------------
182+
// JSInt8Array <-> Int8List
176183
@patch
177184
extension JSInt8ArrayToInt8List on JSInt8Array {
178185
@patch
@@ -187,7 +194,8 @@ extension Int8ListToJSInt8Array on Int8List {
187194
JSInt8Array get toJS => this as JSInt8Array;
188195
}
189196

190-
/// [JSUint8Array] <-> [Uint8List]
197+
// -----------------------------------------------------------------------------
198+
// JSUint8Array <-> Uint8List
191199
@patch
192200
extension JSUint8ArrayToUint8List on JSUint8Array {
193201
@patch
@@ -202,7 +210,8 @@ extension Uint8ListToJSUint8Array on Uint8List {
202210
JSUint8Array get toJS => this as JSUint8Array;
203211
}
204212

205-
/// [JSUint8ClampedArray] <-> [Uint8ClampedList]
213+
// -----------------------------------------------------------------------------
214+
// JSUint8ClampedArray <-> Uint8ClampedList
206215
@patch
207216
extension JSUint8ClampedArrayToUint8ClampedList on JSUint8ClampedArray {
208217
@patch
@@ -217,7 +226,8 @@ extension Uint8ClampedListToJSUint8ClampedArray on Uint8ClampedList {
217226
JSUint8ClampedArray get toJS => this as JSUint8ClampedArray;
218227
}
219228

220-
/// [JSInt16Array] <-> [Int16List]
229+
// -----------------------------------------------------------------------------
230+
// JSInt16Array <-> Int16List
221231
@patch
222232
extension JSInt16ArrayToInt16List on JSInt16Array {
223233
@patch
@@ -232,7 +242,8 @@ extension Int16ListToJSInt16Array on Int16List {
232242
JSInt16Array get toJS => this as JSInt16Array;
233243
}
234244

235-
/// [JSUint16Array] <-> [Uint16List]
245+
// -----------------------------------------------------------------------------
246+
// JSUint16Array <-> Uint16List
236247
@patch
237248
extension JSUint16ArrayToInt16List on JSUint16Array {
238249
@patch
@@ -247,7 +258,8 @@ extension Uint16ListToJSInt16Array on Uint16List {
247258
JSUint16Array get toJS => this as JSUint16Array;
248259
}
249260

250-
/// [JSInt32Array] <-> [Int32List]
261+
// -----------------------------------------------------------------------------
262+
// JSInt32Array <-> Int32List
251263
@patch
252264
extension JSInt32ArrayToInt32List on JSInt32Array {
253265
@patch
@@ -262,7 +274,8 @@ extension Int32ListToJSInt32Array on Int32List {
262274
JSInt32Array get toJS => this as JSInt32Array;
263275
}
264276

265-
/// [JSUint32Array] <-> [Uint32List]
277+
// -----------------------------------------------------------------------------
278+
// JSUint32Array <-> Uint32List
266279
@patch
267280
extension JSUint32ArrayToUint32List on JSUint32Array {
268281
@patch
@@ -277,7 +290,8 @@ extension Uint32ListToJSUint32Array on Uint32List {
277290
JSUint32Array get toJS => this as JSUint32Array;
278291
}
279292

280-
/// [JSFloat32Array] <-> [Float32List]
293+
// -----------------------------------------------------------------------------
294+
// JSFloat32Array <-> Float32List
281295
@patch
282296
extension JSFloat32ArrayToFloat32List on JSFloat32Array {
283297
@patch
@@ -292,7 +306,8 @@ extension Float32ListToJSFloat32Array on Float32List {
292306
JSFloat32Array get toJS => this as JSFloat32Array;
293307
}
294308

295-
/// [JSFloat64Array] <-> [Float64List]
309+
// -----------------------------------------------------------------------------
310+
// JSFloat64Array <-> Float64List
296311
@patch
297312
extension JSFloat64ArrayToFloat64List on JSFloat64Array {
298313
@patch
@@ -307,7 +322,8 @@ extension Float64ListToJSFloat64Array on Float64List {
307322
JSFloat64Array get toJS => this as JSFloat64Array;
308323
}
309324

310-
/// [JSArray] <-> [List]
325+
// -----------------------------------------------------------------------------
326+
// JSArray <-> List
311327
@patch
312328
extension JSArrayToList<T extends JSAny?> on JSArray<T> {
313329
@patch
@@ -339,7 +355,8 @@ extension ListToJSArray<T extends JSAny?> on List<T> {
339355
JSArray<T> get toJSProxyOrRef => this as JSArray<T>;
340356
}
341357

342-
/// [JSNumber] -> [double] or [int].
358+
// -----------------------------------------------------------------------------
359+
// JSNumber -> double or int
343360
@patch
344361
extension JSNumberToNumber on JSNumber {
345362
@patch
@@ -351,15 +368,17 @@ extension JSNumberToNumber on JSNumber {
351368
int get toDartInt => this as int;
352369
}
353370

354-
/// [double] -> [JSNumber].
371+
// -----------------------------------------------------------------------------
372+
// double -> JSNumber
355373
@patch
356374
extension DoubleToJSNumber on double {
357375
@patch
358376
@pragma('dart2js:prefer-inline')
359377
JSNumber get toJS => JSNumber._(this);
360378
}
361379

362-
/// [JSBoolean] <-> [bool]
380+
// -----------------------------------------------------------------------------
381+
// JSBoolean <-> bool
363382
@patch
364383
extension JSBooleanToBool on JSBoolean {
365384
@patch
@@ -374,7 +393,8 @@ extension BoolToJSBoolean on bool {
374393
JSBoolean get toJS => JSBoolean._(this);
375394
}
376395

377-
/// [JSString] <-> [String]
396+
// -----------------------------------------------------------------------------
397+
// JSString <-> String
378398
@patch
379399
extension JSStringToString on JSString {
380400
@patch

sdk/lib/_internal/js_shared/lib/js_types.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ typedef JSBigIntRepType = interceptors.JavaScriptBigInt;
6666

6767
// While this type is not a JS type, it is here for convenience so we don't need
6868
// to create a new shared library.
69-
typedef ExternalDartReferenceRepType = Object;
69+
typedef ExternalDartReferenceRepType<T> = T;
7070

7171
// JSVoid is just a typedef for void.
7272
typedef JSVoidRepType = void;

0 commit comments

Comments
 (0)