diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c82b350a8d..f82dede9d65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,7 +57,9 @@ case in Dart2JS and DDC. We used either `self` or DDC's `global` in non-static interop APIs with `package:js`. So, static interop APIs will now use one of those global contexts. Functionally, this should matter in only a very small - number of cases, like when using older browser versions. + number of cases, like when using older browser versions. `dart:js_interop`'s + `globalJSObject` is also renamed to `globalContext` and returns the global + context used in the lowerings. ## 3.1.0 diff --git a/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart b/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart index f6f7545a96a..6ebba4e0d99 100644 --- a/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart +++ b/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart @@ -27,7 +27,7 @@ class ExportCreator extends Transformer { final ExportChecker _exportChecker; final Procedure _functionToJS; final Procedure _getProperty; - final Procedure _globalJSObject; + final Procedure _globalContext; final Class _jsAny; final Class _jsObject; final Procedure _setProperty; @@ -48,8 +48,8 @@ class ExportCreator extends Transformer { 'dart:js_interop', 'FunctionToJSExportedDartFunction|get#toJS'), _getProperty = _typeEnvironment.coreTypes.index.getTopLevelProcedure( 'dart:js_interop_unsafe', 'JSObjectUtilExtension|[]'), - _globalJSObject = _typeEnvironment.coreTypes.index - .getTopLevelProcedure('dart:js_interop', 'get:globalJSObject'), + _globalContext = _typeEnvironment.coreTypes.index + .getTopLevelProcedure('dart:js_interop', 'get:globalContext'), _jsAny = _typeEnvironment.coreTypes.index .getClass('dart:_js_types', 'JSAny'), _jsObject = _typeEnvironment.coreTypes.index @@ -201,7 +201,7 @@ class ExportCreator extends Transformer { // Get the global 'Object' property. Expression getObjectProperty() => asJSObject(StaticInvocation(_getProperty, - Arguments([StaticGet(_globalJSObject), toJSString('Object')]))) + Arguments([StaticGet(_globalContext), toJSString('Object')]))) ..fileOffset = node.fileOffset; // Get a fresh object literal, using the proto to create it if one was diff --git a/sdk/lib/_internal/js_shared/lib/js_interop_patch.dart b/sdk/lib/_internal/js_shared/lib/js_interop_patch.dart index 0d489d29831..a2afcadd61d 100644 --- a/sdk/lib/_internal/js_shared/lib/js_interop_patch.dart +++ b/sdk/lib/_internal/js_shared/lib/js_interop_patch.dart @@ -5,13 +5,14 @@ import 'dart:_foreign_helper' as foreign_helper; import 'dart:_interceptors' show JavaScriptObject; import 'dart:_internal' show patch; +import 'dart:_js_helper' show staticInteropGlobalContext; import 'dart:_js_types'; import 'dart:js_util' as js_util; import 'dart:typed_data'; @patch @pragma('dart2js:prefer-inline') -JSObject get globalJSObject => js_util.globalThis as JSObject; +JSObject get globalContext => staticInteropGlobalContext as JSObject; /// Helper for working with the [JSAny?] top type in a backend agnostic way. /// TODO(joshualitt): Remove conflation of null and undefined after migration. diff --git a/sdk/lib/_internal/wasm/lib/js_interop_patch.dart b/sdk/lib/_internal/wasm/lib/js_interop_patch.dart index b89e983b08f..044ee379a2f 100644 --- a/sdk/lib/_internal/wasm/lib/js_interop_patch.dart +++ b/sdk/lib/_internal/wasm/lib/js_interop_patch.dart @@ -17,10 +17,9 @@ import 'dart:typed_data'; /// TODO(joshualitt): Find a way to get rid of the explicit casts. T _box(WasmExternRef? ref) => JSValue(ref) as T; -// TODO(joshualitt): Eventually delete `dart:js_util` on Dart2Wasm and migrate -// any used logic to this file. +// This should match the global context we use in our static interop lowerings. @patch -JSObject get globalJSObject => js_util.globalThis as JSObject; +JSObject get globalContext => js_util.globalThis as JSObject; /// Helper for working with the [JSAny?] top type in a backend agnostic way. @patch diff --git a/sdk/lib/js_interop/js_interop.dart b/sdk/lib/js_interop/js_interop.dart index 15d9a0eefdd..36e4d5f844f 100644 --- a/sdk/lib/js_interop/js_interop.dart +++ b/sdk/lib/js_interop/js_interop.dart @@ -136,8 +136,9 @@ typedef JSBoolean = js_types.JSBoolean; /// The type of JS strings, [JSString] <: [JSAny]. typedef JSString = js_types.JSString; -/// A getter to retrieve the Global [JSObject]. -external JSObject get globalJSObject; +/// A getter to retrieve the global context that is used in static interop +/// lowering. +external JSObject get globalContext; /// `JSUndefined` and `JSNull` are actual reified types on some backends, but /// not others. Instead, users should use nullable types for any type that could diff --git a/tests/lib/js_interop_unsafe/basic_test.dart b/tests/lib/js_interop_unsafe/basic_test.dart index 820761f0fec..f5becd4c2a0 100644 --- a/tests/lib/js_interop_unsafe/basic_test.dart +++ b/tests/lib/js_interop_unsafe/basic_test.dart @@ -44,11 +44,11 @@ void equalTest() { globalThis.funcData = function JSClass() {} globalThis.JSClass = new globalThis.funcData(); '''); - JSObject gt = globalJSObject; + JSObject gc = globalContext; void test(String propertyName, bool testCanonicalization) { - Expect.equals(gt[propertyName.toJS], gt[propertyName.toJS]); + Expect.equals(gc[propertyName.toJS], gc[propertyName.toJS]); if (testCanonicalization) { - Expect.equals(gt[propertyName.toJS], gt[(propertyName + "2").toJS]); + Expect.equals(gc[propertyName.toJS], gc[(propertyName + "2").toJS]); } } @@ -83,11 +83,11 @@ void typeofTest() { }; void test(String property, String expectedType) { Expect.isTrue( - globalJSObject[property.toJS]?.typeofEquals(expectedType.toJS).toDart); + globalContext[property.toJS]?.typeofEquals(expectedType.toJS).toDart); for (final type in types) { if (type != expectedType) { Expect.isFalse( - globalJSObject[property.toJS]?.typeofEquals(type.toJS).toDart); + globalContext[property.toJS]?.typeofEquals(type.toJS).toDart); } } } @@ -109,10 +109,10 @@ void instanceOfTest() { globalThis.obj = new JSClass1(); '''); - JSObject gt = globalJSObject; - JSObject obj = gt['obj'.toJS] as JSObject; - JSFunction jsClass1Constructor = gt['JSClass1'.toJS] as JSFunction; - JSFunction jsClass2Constructor = gt['JSClass2'.toJS] as JSFunction; + JSObject gc = globalContext; + JSObject obj = gc['obj'.toJS] as JSObject; + JSFunction jsClass1Constructor = gc['JSClass1'.toJS] as JSFunction; + JSFunction jsClass2Constructor = gc['JSClass2'.toJS] as JSFunction; Expect.isTrue(obj.instanceof(jsClass1Constructor).toDart); Expect.isFalse(obj.instanceof(jsClass2Constructor).toDart); } @@ -151,8 +151,8 @@ void evalAndConstructTest() { } globalThis.JSClass = JSClass; '''); - JSObject gt = globalJSObject; - JSFunction constructor = gt['JSClass'.toJS] as JSFunction; + JSObject gc = globalContext; + JSFunction constructor = gc['JSClass'.toJS] as JSFunction; // Var args JSObject jsObj1 = @@ -267,17 +267,17 @@ void deepConversionsTest() { globalThis.keyObject1 = keyObject; globalThis.keyObject2 = keyObject; '''); - JSObject gt = globalJSObject; - Expect.isNull(gt['a'.toJS]); - Expect.equals('foo', gt.getProperty('b'.toJS).toDart); + JSObject gc = globalContext; + Expect.isNull(gc['a'.toJS]); + Expect.equals('foo', gc.getProperty('b'.toJS).toDart); _expectRecEquals( ['a', 'b', 'c'], - gt + gc .getProperty('c'.toJS) .toDart .map((JSAny? o) => (o as JSString).toDart)); - Expect.equals(2.5, gt.getProperty('d'.toJS).toDartDouble); - Expect.equals(true, gt.getProperty('e'.toJS).toDart); + Expect.equals(2.5, gc.getProperty('d'.toJS).toDartDouble); + Expect.equals(true, gc.getProperty('e'.toJS).toDart); _expectRecEquals({ 'null': 'foo', 'foo': null, @@ -289,40 +289,40 @@ void deepConversionsTest() { 'f': 2, 'g': [2, 4, 6] }, - }, gt.getProperty('g'.toJS).dartify()); + }, gc.getProperty('g'.toJS).dartify()); _expectRecEquals({ 'a': {}, - }, gt.getProperty('rec'.toJS).dartify()); + }, gc.getProperty('rec'.toJS).dartify()); _expectIterableEquals(Int8List.fromList([-128, 0, 127]), - gt.getProperty('int8Array'.toJS).toDart); + gc.getProperty('int8Array'.toJS).toDart); _expectIterableEquals(Uint8List.fromList([-1, 0, 255, 256]), - gt.getProperty('uint8Array'.toJS).toDart); + gc.getProperty('uint8Array'.toJS).toDart); _expectIterableEquals(Uint8ClampedList.fromList([-1, 0, 255, 256]), - gt.getProperty('uint8ClampedArray'.toJS).toDart); + gc.getProperty('uint8ClampedArray'.toJS).toDart); _expectIterableEquals(Int16List.fromList([-32769, -32768, 0, 32767, 32768]), - gt.getProperty('int16Array'.toJS).toDart); + gc.getProperty('int16Array'.toJS).toDart); _expectIterableEquals(Uint16List.fromList([-1, 0, 65535, 65536]), - gt.getProperty('uint16Array'.toJS).toDart); + gc.getProperty('uint16Array'.toJS).toDart); _expectIterableEquals(Int32List.fromList([-2147483648, 0, 2147483647]), - gt.getProperty('int32Array'.toJS).toDart); + gc.getProperty('int32Array'.toJS).toDart); _expectIterableEquals(Uint32List.fromList([-1, 0, 4294967295, 4294967296]), - gt.getProperty('uint32Array'.toJS).toDart); + gc.getProperty('uint32Array'.toJS).toDart); _expectIterableEquals( Float32List.fromList([-1000.488, -0.00001, 0.0001, 10004.888]), - gt.getProperty('float32Array'.toJS).toDart); + gc.getProperty('float32Array'.toJS).toDart); _expectIterableEquals( Float64List.fromList([-1000.488, -0.00001, 0.0001, 10004.888]), - gt.getProperty('float64Array'.toJS).toDart); + gc.getProperty('float64Array'.toJS).toDart); _expectIterableEquals(Uint8List.fromList([-1, 0, 255, 256]), - gt.getProperty('arrayBuffer'.toJS).toDart.asUint8List()); + gc.getProperty('arrayBuffer'.toJS).toDart.asUint8List()); _expectIterableEquals(Uint8List.fromList([-1, 0, 255, 256]), - gt.getProperty('dataView'.toJS).toDart.buffer.asUint8List()); + gc.getProperty('dataView'.toJS).toDart.buffer.asUint8List()); // Confirm a function that takes a roundtrip remains a function. - JSFunction foo = gt['f'.toJS].dartify() as JSFunction; + JSFunction foo = gc['f'.toJS].dartify() as JSFunction; Expect.equals( - 'hello world', gt.callMethod('invoke'.toJS, foo).toDart); + 'hello world', gc.callMethod('invoke'.toJS, foo).toDart); // Confirm arrays, which need to be converted implicitly, are still // recursively converted by dartify() when desired. @@ -334,12 +334,12 @@ void deepConversionsTest() { 3, {'baz': 'boo'} ], - ], gt['implicitExplicit'.toJS].dartify() as Iterable); + ], gc['implicitExplicit'.toJS].dartify() as Iterable); // Test that JS objects behave as expected in Map / Set. Set set = {}; - JSAny? key1 = gt['keyObject1'.toJS]; - JSAny? key2 = gt['keyObject2'.toJS]; + JSAny? key1 = gc['keyObject1'.toJS]; + JSAny? key2 = gc['keyObject2'.toJS]; Expect.isTrue(set.add(key1)); Expect.isTrue(set.contains(key1)); Expect.isFalse(set.add(key2)); @@ -384,17 +384,17 @@ void symbolTest() { } globalThis.symbol2 = symbol2; '''); - JSObject gt = globalJSObject; + JSObject gc = globalContext; Expect.equals( _JSSymbol.keyFor(_JSSymbol._for('symbol'.toJS)).toDart, 'symbol'); Expect.equals( - gt.getProperty(gt.getProperty('symbol'.toJS)).toDart, + gc.getProperty(gc.getProperty('symbol'.toJS)).toDart, 'boo'); Expect.equals(methodWithSymbol(symbol).toDart, 'symbol'); Expect.equals(_JSSymbol.keyFor(symbol).toDart, 'symbol'); Expect.equals( - _JSSymbol.keyFor(gt.getProperty('symbol'.toJS)).toDart, 'symbol'); - Expect.equals(gt.callMethod(symbol2).toDart, 'hello world'); + _JSSymbol.keyFor(gc.getProperty('symbol'.toJS)).toDart, 'symbol'); + Expect.equals(gc.callMethod(symbol2).toDart, 'hello world'); } void main() {