diff --git a/test_files/source/js_interop.dart b/test_files/source/js_interop.dart deleted file mode 100644 index f9122bc..0000000 --- a/test_files/source/js_interop.dart +++ /dev/null @@ -1,1124 +0,0 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -/// Interoperability, "interop" for short, with JavaScript and browser APIs. -/// -/// JavaScript interop allows a Dart program to interact with a JavaScript -/// runtime. This can, for example, be to access JavaScript declarations and -/// interact with JavaScript values, or to adapt Dart values so that they can be -/// passed to and used by JavaScript code. -/// -/// This JavaScript interop library works by introducing an abstraction over -/// JavaScript values, a Dart type hierarchy ("JS types") which mirrors known -/// JavaScript types, and a framework for introducing new Dart types that bind -/// Dart type declarations to JavaScript values and external member declarations -/// to JavaScript APIs. -/// -/// This abstraction allows the same interop API to be used both when the Dart -/// code is compiled to JavaScript and when compiled to Wasm. -/// -/// See https://dart.dev/interop/js-interop for more details on usage, types, -/// and previous JavaScript interop. -/// -/// > [!NOTE] -/// > The types defined in this library only provide static guarantees. -/// > The runtime types differ based on the backend, so it is important to rely -/// > on static functionality like the conversion functions, for example `toJS` -/// > and not runtime mechanisms like type checks (`is`) and casts (`as`). -/// -/// {@category Web} -library; - -import 'dart:_internal' show Since; -import 'dart:_js_annotations' show JSExport; -import 'dart:_js_types'; -import 'dart:js_interop_unsafe'; -import 'dart:typed_data'; - -// To support an easier transition, we allow users to use `@staticInterop` -// classes - with or without the `@anonymous` annotation. -export 'dart:_js_annotations' show staticInterop, anonymous, JSExport; -export 'dart:js_util' show NullRejectionException; - -/// An annotation on a JavaScript interop declaration. -/// -/// This annotation defines a given library, top-level external declaration, or -/// extension type as a JavaScript interop declaration. -/// -/// Specifying [name] customizes the JavaScript name to use, which can be used -/// in the following scenarios: -/// -/// - Adding a JavaScript prefix to all the external top-level declarations, -/// static members, and constructors of a library by parameterizing the -/// annotation on the library with [name]. -/// - Specifying the JavaScript class to use for external static members and -/// constructors of an interop extension type by parameterizing the annotation -/// on the interop extension type with [name]. -/// - Renaming external declarations by parameterizing the annotation on the -/// member with [name]. -/// -/// In the case where [name] is not specified, the Dart name of the extension -/// type or external declaration is used as the default. -/// -/// See https://dart.dev/interop/js-interop/usage#js for more details on how to -/// use this annotation. -/// -/// > [!NOTE] -/// > `package:js` exports an `@JS` annotation as well. Unlike that annotation, -/// > this annotation applies to extension types, and will result in more -/// > type-checking for external top-level declarations. -class JS { - final String? name; - const JS([this.name]); -} - -/// A non-nullish JavaScript value. -/// -/// A [JSAny] can be any JavaScript value except JavaScript `null` and -/// `undefined`. JavaScript `null` and `undefined` are instead converted to Dart -/// `null` by the compiler. Therefore, [JSAny]? is the top type of -/// the type hierarchy as it includes nullish JavaScript values as well. -extension type JSAny._(JSAnyRepType _jsAny) implements Object {} - -/// A JavaScript `Object`. -/// -/// [JSObject] is the supertype of all JavaScript objects, but not other JS -/// types, like primitives. See https://dart.dev/interop/js-interop for more -/// details on how to use JavaScript interop. -/// -/// When declaring interop extension types, [JSObject] is usually the type you -/// will use as the representation type. -@JS('Object') -extension type JSObject._(JSObjectRepType _jsObject) implements JSAny { - /// Creates a [JSObject] from an object provided by an earlier interop - /// library. - /// - /// Accepts, for example, the types created using `package:js` or `dart:html`. - /// - /// This constructor is intended to allow users to avoid having to cast to and - /// from [JSObject]. - JSObject.fromInteropObject(Object interopObject) - : _jsObject = interopObject as JSObjectRepType; - - /// Creates a new empty JavaScript object. - /// - /// The object is created using the JavaScript object initializer syntax - /// (`{}`), and this constructor is more efficient than `{}.jsify()`. - JSObject() : _jsObject = _createObjectLiteral(); -} - -// TODO(srujzs): Move this member to `JSObject` once we can patch extension type -// members. -external JSObjectRepType _createObjectLiteral(); - -/// A JavaScript [`Function`](https://tc39.es/ecma262/#sec-function-objects) -/// value. -@JS('Function') -extension type JSFunction._(JSFunctionRepType _jsFunction) - implements JSObject {} - -/// A JavaScript callable function created from a Dart function. -/// -/// See [FunctionToJSExportedDartFunction.toJS] for more details on how to -/// convert a Dart function. -@JS('Function') -extension type JSExportedDartFunction._( - JSExportedDartFunctionRepType _jsExportedDartFunction) - implements JSFunction {} - -/// A JavaScript [`Array`](https://tc39.es/ecma262/#sec-array-objects). -/// -/// Because [JSArray] is an extension type, [T] is only a static guarantee and -/// the array does not necessarily only contain [T] elements. For example: -/// -/// ```dart -/// @JS() -/// external JSArray get array; -/// ``` -/// -/// `array` is not actually checked to ensure it contains instances of -/// [JSNumber] when called. -/// -/// [T] may introduce additional checking elsewhere, however. When accessing -/// elements of [JSArray] with type [T], there is a check to ensure the element -/// is a [T] to ensure soundness. Similarly, when converting to a [List], -/// casts may be introduced to ensure that it is indeed a [List]. -@JS('Array') -extension type JSArray._(JSArrayRepType _jsArray) - implements JSObject { - /// Creates an empty JavaScript `Array`. - /// - /// Equivalent to `new Array()` and more efficient than `[].jsify()`. - external JSArray(); - - /// Creates a JavaScript `Array` of size [length] with no elements. - external JSArray.withLength(int length); -} - -/// A JavaScript `Promise` or a promise-like object. -/// -/// Because [JSPromise] is an extension type, [T] is only a static guarantee and -/// the [JSPromise] may not actually resolve to a [T]. -/// -/// Also like with [JSArray], [T] may introduce additional checking elsewhere. -/// When converted to a [Future], there is a cast to ensure that the [Future] -/// actually resolves to a [T] to ensure soundness. -@JS('Promise') -extension type JSPromise._(JSPromiseRepType _jsPromise) - implements JSObject { - external JSPromise(JSFunction executor); -} - -/// A Dart object that is wrapped with a JavaScript object so that it can be -/// passed to JavaScript safely. -/// -/// Use this interface when you want to pass Dart objects within the same -/// runtime through JavaScript. There are no usable members in the resulting -/// [JSBoxedDartObject]. -/// -/// See [ObjectToJSBoxedDartObject.toJSBox] to wrap an arbitrary [Object]. -@JS('Object') -extension type JSBoxedDartObject._(JSBoxedDartObjectRepType _jsBoxedDartObject) - implements JSObject {} - -/// A JavaScript `ArrayBuffer`. -@JS('ArrayBuffer') -extension type JSArrayBuffer._(JSArrayBufferRepType _jsArrayBuffer) - implements JSObject {} - -/// A JavaScript `DataView`. -@JS('DataView') -extension type JSDataView._(JSDataViewRepType _jsDataView) - implements JSObject {} - -/// Abstract supertype of all JavaScript typed arrays. -extension type JSTypedArray._(JSTypedArrayRepType _jsTypedArray) - implements JSObject {} - -/// A JavaScript `Int8Array`. -@JS('Int8Array') -extension type JSInt8Array._(JSInt8ArrayRepType _jsInt8Array) - implements JSTypedArray {} - -/// A JavaScript `Uint8Array`. -@JS('Uint8Array') -extension type JSUint8Array._(JSUint8ArrayRepType _jsUint8Array) - implements JSTypedArray {} - -/// A JavaScript `Uint8ClampedArray`. -@JS('Uint8ClampedArray') -extension type JSUint8ClampedArray._( - JSUint8ClampedArrayRepType _jsUint8ClampedArray) implements JSTypedArray {} - -/// A JavaScript `Int16Array`. -@JS('Int16Array') -extension type JSInt16Array._(JSInt16ArrayRepType _jsInt16Array) - implements JSTypedArray {} - -/// A JavaScript `Uint16Array`. -@JS('Uint16Array') -extension type JSUint16Array._(JSUint16ArrayRepType _jsUint16Array) - implements JSTypedArray {} - -/// A JavaScript `Int32Array`. -@JS('Int32Array') -extension type JSInt32Array._(JSInt32ArrayRepType _jsInt32Array) - implements JSTypedArray {} - -/// A JavaScript `Uint32Array`. -@JS('Uint32Array') -extension type JSUint32Array._(JSUint32ArrayRepType _jsUint32Array) - implements JSTypedArray {} - -/// A JavaScript `Float32Array`. -@JS('Float32Array') -extension type JSFloat32Array._(JSFloat32ArrayRepType _jsFloat32Array) - implements JSTypedArray {} - -/// A JavaScript `Float64Array`. -@JS('Float64Array') -extension type JSFloat64Array._(JSFloat64ArrayRepType _jsFloat64Array) - implements JSTypedArray {} - -// The various JavaScript primitive types. Crucially, unlike the Dart type -// hierarchy, none of these types are subtypes of [JSObject]. They are just -// subtypes of [JSAny]. - -/// A JavaScript number. -extension type JSNumber._(JSNumberRepType _jsNumber) implements JSAny {} - -/// A JavaScript boolean. -extension type JSBoolean._(JSBooleanRepType _jsBoolean) implements JSAny {} - -/// A JavaScript string. -extension type JSString._(JSStringRepType _jsString) implements JSAny {} - -/// A JavaScript `Symbol`. -extension type JSSymbol._(JSSymbolRepType _jsSymbol) implements JSAny {} - -/// A JavaScript `BigInt`. -extension type JSBigInt._(JSBigIntRepType _jsBigInt) implements JSAny {} - -/// JS type equivalent for `undefined` for interop member return types. -/// -/// Prefer using `void` instead of this. -// TODO(srujzs): Mark this as deprecated. There are no performance costs from -// using `void`, and we'll likely provide a different way to box `undefined`. -typedef JSVoid = JSVoidRepType; - -/// Helper methods to determine if a value is JavaScript `undefined` or `null`. -/// -/// > [!NOTE] -/// > The members within these extensions may throw depending on the platform. -/// > Do not rely on them to be platform-consistent. -/// -/// JavaScript `undefined` and JavaScript `null` are internalized differently -/// based on the backend. When compiling to JavaScript, Dart `null` can actually -/// be JavaScript `undefined` or JavaScript `null`. When compiling to Wasm, -/// that's not the case: there's only one Wasm value `null` can be. Therefore, -/// when an interop API returns JavaScript `null` or JavaScript `undefined`, -/// they are both converted to Dart `null` when compiling to Wasm, and when you -/// pass a Dart `null` to an interop API, it is called with JavaScript `null`. -/// When compiling to JavaScript, Dart `null` retains its original JavaScript -/// value. Avoid writing code where this distinction between `null` and -/// `undefined` matters. -// TODO(srujzs): Investigate what it takes to allow users to distinguish between -// the two "nullish" values. An annotation-based model where users annotate -// interop APIs to internalize `undefined` differently seems promising, but does -// not handle some cases like converting a `JSArray` with `undefined`s in it to -// `List`. In this case, the implementation of the list wrapper needs to -// make the decision, not the user. -extension NullableUndefineableJSAnyExtension on JSAny? { - /// Whether this value corresponds to JavaScript `undefined`. - /// - /// > [!NOTE] - /// > Currently, there is no way to distinguish between JavaScript `undefined` - /// > and JavaScript `null` when compiling to Wasm. Therefore, this getter - /// > should only be used for code that compiles to JavaScript and will throw - /// > when compiling to Wasm. - external bool get isUndefined; - - /// Whether this value corresponds to JavaScript `null`. - /// - /// > [!NOTE] - /// > Currently, there is no way to distinguish between JavaScript `undefined` - /// > and JavaScript `null` when compiling to Wasm. Therefore, this getter - /// > should only be used for code that compiles to JavaScript and will throw - /// > when compiling to Wasm. - external bool get isNull; - - bool get isUndefinedOrNull => this == null; - bool get isDefinedAndNotNull => !isUndefinedOrNull; -} - -/// Common utility functions that are useful for any JavaScript value. -extension JSAnyUtilityExtension on JSAny? { - /// Whether the result of `typeof` on this [JSAny]? is - /// [typeString]. - external bool typeofEquals(String typeString); - - /// Whether this [JSAny]? is an `instanceof` [constructor]. - external bool instanceof(JSFunction constructor); - - /// Whether this [JSAny]? is an `instanceof` the constructor that - /// is defined by [constructorName], which is looked up in the - /// [globalContext]. - /// - /// If [constructorName] contains '.'s, the name is split into several parts - /// in order to get the constructor. For example, `library1.JSClass` would - /// involve fetching `library1` off of the [globalContext], and then fetching - /// `JSClass` off of `library1` to get the constructor. - /// - /// If [constructorName] is empty or any of the parts or the constructor don't - /// exist, returns false. - bool instanceOfString(String constructorName) { - if (constructorName.isEmpty) return false; - final parts = constructorName.split('.'); - JSObject? constructor = globalContext; - for (final part in parts) { - constructor = constructor?[part] as JSObject?; - if (constructor == null) return false; - } - return instanceof(constructor as JSFunction); - } - - /// Whether this [JSAny]? is an instance of the JavaScript type - /// that is declared by [T]. - /// - /// This method uses a combination of null, `typeof`, and `instanceof` checks - /// in order to do this check. Use this instead of `is` checks. - /// - /// If [T] is a primitive JS type like [JSString], this uses a `typeof` check - /// that corresponds to that primitive type like `typeofEquals('string')`. - /// - /// If [T] is a non-primitive JS type like [JSArray] or an interop extension - /// type on one, this uses an `instanceof` check using the name or the - /// @[JS] rename of the given type like - /// `instanceOfString('Array')`. Note that if you rename the library using the - /// @[JS] annotation, this uses the rename in the `instanceof` - /// check like `instanceOfString('library1.JSClass')`. - /// - /// To determine the JavaScript constructor to use as the second operand in - /// the `instanceof` check, this function uses the JavaScript name associated - /// with the extension type, which is either the argument given to the - /// @[JS] annotation or the Dart declaration name. So, if you had - /// an interop extension type `JSClass` that wraps `JSArray` without a rename, - /// this does an `instanceOfString('JSClass')` check and not an - /// `instanceOfString('Array')` check. - /// - /// There are two exceptions to this rule. The first exception is - /// `JSTypedArray`. As `TypedArray` does not exist as a property in - /// JavaScript, this does some prototype checking to make `isA` - /// do the right thing. The other exception is `JSAny`. If you do a - /// `isA` check, it will only do a null-check. - /// - /// Using this method with a [T] that has an object literal constructor will - /// result in an error as you likely want to use [JSObject] instead. - /// - /// Using this method with a [T] that wraps a primitive JS type will result in - /// an error telling you to use the primitive JS type instead. - @Since('3.4') - external bool isA(); - - /// Converts a JavaScript value to the Dart equivalent if possible. - /// - /// Effectively the inverse of [NullableObjectUtilExtension.jsify], [dartify] - /// takes a JavaScript value and recursively converts it to a Dart object. - /// Only JavaScript primitives, `Array`s, typed arrays, and map-like objects - /// with string property names are supported. - /// - /// > [!NOTE] - /// > Prefer using the specific conversion method like `toDart` if you know - /// > the JavaScript type as this method may perform many type-checks. - // TODO(srujzs): We likely need stronger tests for this method to ensure - // consistency. - external Object? dartify(); -} - -/// Common utility functions for [Object]?s. -extension NullableObjectUtilExtension on Object? { - /// Converts a Dart object to the JavaScript equivalent if possible. - /// - /// Effectively the inverse of [JSAnyUtilityExtension.dartify], [jsify] takes - /// a Dart object and recursively converts it to a JavaScript value. Only Dart - /// primitives, [Iterable]s, typed lists, and [Map]s are supported. - /// - /// > [!NOTE] - /// > Prefer using the specific conversion method like `toJS` if you know the - /// > Dart type as this method may perform many type-checks. - // TODO(srujzs): We likely need stronger tests for this method to ensure - // consistency. - external JSAny? jsify(); -} - -/// Utility extensions for [JSFunction]. -// TODO(srujzs): We may want to provide a syntax for users to avoid `.call` and -// directly call the function in JavaScript using `(...)`. -extension JSFunctionUtilExtension on JSFunction { - /// Call this [JSFunction] using the JavaScript `.call` syntax and returns the - /// result. - /// - /// Takes at most 4 args for consistency with other APIs and relative brevity. - /// If more are needed, you can declare your own external member with the same - /// syntax. - // We rename this function since declaring a `call` member makes a class - // callable in Dart. This is convenient, but unlike Dart functions, JavaScript - // functions explicitly take a `this` argument (which users can provide `null` - // for in the case where the function doesn't need it), which may lead to - // confusion. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call - @JS('call') - external JSAny? callAsFunction( - [JSAny? thisArg, JSAny? arg1, JSAny? arg2, JSAny? arg3, JSAny? arg4]); -} - -// Extension members to support conversions between Dart types and JS types. -// Not all Dart types can be converted to JS types and vice versa. -// TODO(srujzs): Move some of these to the associated extension type. - -/// Conversions from [JSExportedDartFunction] to [Function]. -extension JSExportedDartFunctionToFunction on JSExportedDartFunction { - /// The Dart [Function] that this [JSExportedDartFunction] wrapped. - /// - /// Must be a wrapped Dart [Function]. - external Function get toDart; -} - -/// Conversions from [Function] to [JSExportedDartFunction]. -extension FunctionToJSExportedDartFunction on Function { - /// A callable JavaScript function that wraps this [Function]. - /// - /// If the static type of the [Function] could not be determined or if - /// the static type uses types that are disallowed, the call will fail to - /// compile. See - /// https://dart.dev/interop/js-interop/js-types#requirements-on-external-declarations-and-function-tojs - /// for more details on what types are allowed. - external JSExportedDartFunction get toJS; -} - -/// Conversions from [JSBoxedDartObject] to [Object]. -extension JSBoxedDartObjectToObject on JSBoxedDartObject { - /// The Dart [Object] that this [JSBoxedDartObjectToObject] wrapped. - /// - /// Throws an [Exception] if the Dart runtime was not the same as the one in - /// which the [Object] was wrapped or if this was not a wrapped Dart [Object]. - external Object get toDart; -} - -/// Conversions from [Object] to [JSBoxedDartObject]. -extension ObjectToJSBoxedDartObject on Object { - /// A JavaScript object that wraps this [Object]. - /// - /// There are no usable members in the resulting [JSBoxedDartObject] and you - /// may get a new [JSBoxedDartObject] when calling [toJSBox] on the same Dart - /// [Object]. - external JSBoxedDartObject get toJSBox; -} - -/// Conversions from [JSPromise] to [Future]. -extension JSPromiseToFuture on JSPromise { - /// A [Future] that either completes with the result of the resolved - /// [JSPromise] or propagates the error that the [JSPromise] rejected with. - external Future get toDart; -} - -/// Conversions from [Future] to [JSPromise] where the [Future] returns a value. -extension FutureOfJSAnyToJSPromise on Future { - /// A [JSPromise] that either resolves with the result of the completed - /// [Future] or rejects with an object that contains its error. - /// - /// The rejected object contains the original error as a [JSBoxedDartObject] - /// in the property `error` and the original stack trace as a [String] in the - /// property `stack`. - JSPromise get toJS { - return JSPromise((JSFunction resolve, JSFunction reject) { - this.then((JSAny? value) { - resolve.callAsFunction(resolve, value); - return value; - }, onError: (Object error, StackTrace stackTrace) { - // TODO(srujzs): Can we do something better here? This is pretty much - // useless to the user unless they call a Dart callback that consumes - // this value and unboxes. - final errorConstructor = globalContext['Error'] as JSFunction; - final wrapper = errorConstructor.callAsConstructor( - "Dart exception thrown from converted Future. Use the properties " - "'error' to fetch the boxed error and 'stack' to recover " - "the stack trace." - .toJS); - wrapper['error'] = error.toJSBox; - wrapper['stack'] = stackTrace.toString().toJS; - reject.callAsFunction(reject, wrapper); - return wrapper; - }); - }.toJS); - } -} - -/// Conversions from [Future] to [JSPromise] where the [Future] does not return -/// a value. -extension FutureOfVoidToJSPromise on Future { - /// A [JSPromise] that either resolves once this [Future] completes or rejects - /// with an object that contains its error. - /// - /// The rejected object contains the original error as a [JSBoxedDartObject] - /// in the property `error` and the original stack trace as a [String] in the - /// property `stack`. - JSPromise get toJS { - return JSPromise((JSFunction resolve, JSFunction reject) { - this.then((_) => resolve.callAsFunction(resolve), - onError: (Object error, StackTrace stackTrace) { - // TODO(srujzs): Can we do something better here? This is pretty much - // useless to the user unless they call a Dart callback that consumes - // this value and unboxes. - final errorConstructor = globalContext['Error'] as JSFunction; - final wrapper = errorConstructor.callAsConstructor( - "Dart exception thrown from converted Future. Use the properties " - "'error' to fetch the boxed error and 'stack' to recover " - "the stack trace." - .toJS); - wrapper['error'] = error.toJSBox; - wrapper['stack'] = stackTrace.toString().toJS; - reject.callAsFunction(reject, wrapper); - }); - }.toJS); - } -} - -/// Conversions from [JSArrayBuffer] to [ByteBuffer]. -extension JSArrayBufferToByteBuffer on JSArrayBuffer { - /// Converts this [JSArrayBuffer] to a [ByteBuffer] by either casting or - /// wrapping it. - /// - /// When compiling to JavaScript, [ByteBuffer]s are [JSArrayBuffer]s and this - /// operation will be a cast. When compiling to Wasm, a wrapper is introduced. - /// Modifications to this [JSArrayBuffer] will affect the [ByteBuffer] and - /// vice versa. - external ByteBuffer get toDart; -} - -/// Conversions from [ByteBuffer] to [JSArrayBuffer]. -extension ByteBufferToJSArrayBuffer on ByteBuffer { - /// Converts this [ByteBuffer] to a [JSArrayBuffer] by either casting, - /// unwrapping, or cloning the [ByteBuffer]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [ByteBuffer] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [ByteBuffer]'s values into a new - /// > [JSArrayBuffer]. - /// > Avoid assuming that modifications to this [ByteBuffer] will affect the - /// > [JSArrayBuffer] and vice versa unless it was instantiated in JavaScript. - external JSArrayBuffer get toJS; -} - -/// Conversions from [JSDataView] to [ByteData]. -extension JSDataViewToByteData on JSDataView { - /// Converts this [JSDataView] to a [ByteData] by either casting or wrapping - /// it. - /// - /// When compiling to JavaScript, [ByteData]s are [JSDataView]s and this - /// operation will be a cast. When compiling to Wasm, a wrapper is introduced. - /// Modifications to this [JSDataView] will affect the [ByteData] and vice - /// versa. - external ByteData get toDart; -} - -/// Conversions from [ByteData] to [JSDataView]. -extension ByteDataToJSDataView on ByteData { - /// Converts this [ByteData] to a [JSDataView] by either casting, unwrapping, - /// or cloning the [ByteData]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [ByteData] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [ByteData]'s values into a new - /// > [JSDataView]. - /// > Avoid assuming that modifications to this [ByteData] will affect the - /// > [JSDataView] and vice versa unless it was instantiated in JavaScript. - external JSDataView get toJS; -} - -/// Conversions from [JSInt8Array] to [Int8List]. -extension JSInt8ArrayToInt8List on JSInt8Array { - /// Converts this [JSInt8Array] to a [Int8List] by either casting or wrapping - /// it. - /// - /// When compiling to JavaScript, [Int8List]s are [JSInt8Array]s and this - /// operation will be a cast. When compiling to Wasm, a wrapper is introduced. - /// Modifications to this [JSInt8Array] will affect the [Int8List] and vice - /// versa. - external Int8List get toDart; -} - -/// Conversions from [Int8List] to [JSInt8Array]. -extension Int8ListToJSInt8Array on Int8List { - /// Converts this [Int8List] to a [JSInt8Array] by either casting, - /// unwrapping, or cloning the [Int8List]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [Int8List] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [Int8List]'s values into a new - /// > [JSInt8Array]. - /// > Avoid assuming that modifications to this [Int8List] will affect the - /// > [JSInt8Array] and vice versa unless it was instantiated in JavaScript. - external JSInt8Array get toJS; -} - -/// Conversions from [JSUint8Array] to [Uint8List]. -extension JSUint8ArrayToUint8List on JSUint8Array { - /// Converts this [JSUint8Array] to a [Uint8List] by either casting or - /// wrapping it. - /// - /// When compiling to JavaScript, [Uint8List]s are [JSUint8Array]s and this - /// operation will be a cast. When compiling to Wasm, a wrapper is introduced. - /// Modifications to this [JSUint8Array] will affect the [Uint8List] and vice - /// versa. - external Uint8List get toDart; -} - -/// Conversions from [Uint8List] to [JSUint8Array]. -extension Uint8ListToJSUint8Array on Uint8List { - /// Converts this [Uint8List] to a [JSUint8Array] by either casting, - /// unwrapping, or cloning the [Uint8List]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [Uint8List] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [Uint8List]'s values into a new - /// > [JSUint8Array]. - /// > Avoid assuming that modifications to this [Uint8List] will affect the - /// > [JSUint8Array] and vice versa unless it was instantiated in JavaScript. - external JSUint8Array get toJS; -} - -/// Conversions from [JSUint8ClampedArray] to [Uint8ClampedList]. -extension JSUint8ClampedArrayToUint8ClampedList on JSUint8ClampedArray { - /// Converts this [JSUint8ClampedArray] to a [Uint8ClampedList] by either - /// casting or wrapping it. - /// - /// When compiling to JavaScript, [Uint8ClampedList]s are - /// [JSUint8ClampedArray]s and this operation will be a cast. When compiling - /// to Wasm, a wrapper is introduced. Modifications to this - /// [JSUint8ClampedArray] will affect the [Uint8ClampedList] and vice versa. - external Uint8ClampedList get toDart; -} - -/// Conversions from [Uint8ClampedList] to [JSUint8ClampedArray]. -extension Uint8ClampedListToJSUint8ClampedArray on Uint8ClampedList { - /// Converts this [Uint8ClampedList] to a [JSUint8ClampedArray] by either - /// casting, unwrapping, or cloning the [Uint8ClampedList]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [Uint8ClampedList] may or may not be a - /// > wrapper depending on if it was converted from JavaScript or instantiated - /// > in Dart. If it's a wrapper, this method unwraps it. If it's instantiated - /// > in Dart, this method clones this [Uint8ClampedList]'s values into a new - /// > [JSUint8ClampedArray]. - /// > Avoid assuming that modifications to this [Uint8ClampedList] will affect - /// > the [JSUint8ClampedArray] and vice versa unless it was instantiated in - /// > JavaScript. - external JSUint8ClampedArray get toJS; -} - -/// Conversions from [JSInt16Array] to [Int16List]. -extension JSInt16ArrayToInt16List on JSInt16Array { - /// Converts this [JSInt16Array] to a [Int16List] by either casting or - /// wrapping it. - /// - /// When compiling to JavaScript, [Int16List]s are [JSInt16Array]s and this - /// operation will be a cast. When compiling to Wasm, a wrapper is introduced. - /// Modifications to this [JSInt16Array] will affect the [Int16List] and vice - /// versa. - external Int16List get toDart; -} - -/// Conversions from [Int16List] to [JSInt16Array]. -extension Int16ListToJSInt16Array on Int16List { - /// Converts this [Int16List] to a [JSInt16Array] by either casting, - /// unwrapping, or cloning the [Int16List]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [Int16List] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [Int16List]'s values into a new - /// > [JSInt16Array]. - /// > Avoid assuming that modifications to this [Int16List] will affect the - /// > [JSInt16Array] and vice versa unless it was instantiated in JavaScript. - external JSInt16Array get toJS; -} - -/// Conversions from [JSUint16Array] to [Uint16List]. -extension JSUint16ArrayToInt16List on JSUint16Array { - /// Converts this [JSUint16Array] to a [Uint16List] by either casting or - /// wrapping it. - /// - /// When compiling to JavaScript, [Uint16List]s are [JSUint16Array]s and this - /// operation will be a cast. When compiling to Wasm, a wrapper is introduced. - /// Modifications to this [JSUint16Array] will affect the [Uint16List] and - /// vice versa. - external Uint16List get toDart; -} - -/// Conversions from [Uint16List] to [JSUint16Array]. -extension Uint16ListToJSInt16Array on Uint16List { - /// Converts this [Uint16List] to a [JSUint16Array] by either casting, - /// unwrapping, or cloning the [Uint16List]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [Uint16List] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [Uint16List]'s values into a new - /// > [JSUint16Array]. - /// > Avoid assuming that modifications to this [Uint16List] will affect the - /// > [JSUint16Array] and vice versa unless it was instantiated in JavaScript. - external JSUint16Array get toJS; -} - -/// Conversions from [JSInt32Array] to [Int32List]. -extension JSInt32ArrayToInt32List on JSInt32Array { - /// Converts this [JSInt32Array] to a [Int32List] by either casting or - /// wrapping it. - /// - /// When compiling to JavaScript, [Int32List]s are [JSInt32Array]s and this - /// operation will be a cast. When compiling to Wasm, a wrapper is introduced. - /// Modifications to this [JSInt32Array] will affect the [Int32List] and vice - /// versa. - external Int32List get toDart; -} - -/// Conversions from [Int32List] to [JSInt32Array]. -extension Int32ListToJSInt32Array on Int32List { - /// Converts this [Int32List] to a [JSInt32Array] by either casting, - /// unwrapping, or cloning the [Int32List]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [Int32List] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [Int32List]'s values into a new - /// > [JSInt32Array]. - /// > Avoid assuming that modifications to this [Int32List] will affect the - /// > [JSInt32Array] and vice versa unless it was instantiated in JavaScript. - external JSInt32Array get toJS; -} - -/// Conversions from [JSUint32Array] to [Uint32List]. -extension JSUint32ArrayToUint32List on JSUint32Array { - /// Converts this [JSUint32Array] to a [Uint32List] by either casting or - /// wrapping it. - /// - /// When compiling to JavaScript, [Uint32List]s are [JSUint32Array]s and this - /// operation will be a cast. When compiling to Wasm, a wrapper is introduced. - /// Modifications to this [JSUint32Array] will affect the [Uint32List] and - /// vice versa. - external Uint32List get toDart; -} - -/// Conversions from [Uint32List] to [JSUint32Array]. -extension Uint32ListToJSUint32Array on Uint32List { - /// Converts this [Uint32List] to a [JSUint32Array] by either casting, - /// unwrapping, or cloning the [Uint32List]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [Uint32List] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [Uint32List]'s values into a new - /// > [JSUint32Array]. - /// > Avoid assuming that modifications to this [Uint32List] will affect the - /// > [JSUint32Array] and vice versa unless it was instantiated in JavaScript. - external JSUint32Array get toJS; -} - -/// Conversions from [JSFloat32Array] to [Float32List]. -extension JSFloat32ArrayToFloat32List on JSFloat32Array { - /// Converts this [JSFloat32Array] to a [Float32List] by either casting or - /// wrapping it. - /// - /// When compiling to JavaScript, [Float32List]s are [JSFloat32Array]s and - /// this operation will be a cast. When compiling to Wasm, a wrapper is - /// introduced. Modifications to this [JSFloat32Array] will affect the - /// [Float32List] and vice versa. - external Float32List get toDart; -} - -/// Conversions from [Float32List] to [JSFloat32Array]. -extension Float32ListToJSFloat32Array on Float32List { - /// Converts this [Float32List] to a [JSFloat32Array] by either casting, - /// unwrapping, or cloning the [Float32List]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [Float32List] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [Float32List]'s values into a new - /// > [JSFloat32Array]. - /// > Avoid assuming that modifications to this [Float32List] will affect the - /// > [JSFloat32Array] and vice versa unless it was instantiated in - /// > JavaScript. - external JSFloat32Array get toJS; -} - -/// Conversions from [JSFloat64Array] to [Float64List]. -extension JSFloat64ArrayToFloat64List on JSFloat64Array { - /// Converts this [JSFloat64Array] to a [Float64List] by either casting or - /// wrapping it. - /// - /// When compiling to JavaScript, [Float64List]s are [JSFloat64Array]s and - /// this operation will be a cast. When compiling to Wasm, a wrapper is - /// introduced. Modifications to this [JSFloat64Array] will affect the - /// [Float64List] and vice versa. - external Float64List get toDart; -} - -/// Conversions from [Float64List] to [JSFloat64Array]. -extension Float64ListToJSFloat64Array on Float64List { - /// Converts this [Float64List] to a [JSFloat64Array] by either casting, - /// unwrapping, or cloning the [Float64List]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, all typed lists are the equivalent - /// > JavaScript typed arrays, and therefore this method simply casts. - /// > When compiling to Wasm, this [Float64List] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [Float64List]'s values into a new - /// > [JSFloat64Array]. - /// > Avoid assuming that modifications to this [Float64List] will affect the - /// > [JSFloat64Array] and vice versa unless it was instantiated in - /// > JavaScript. - external JSFloat64Array get toJS; -} - -/// Conversions from [JSArray] to [List]. -extension JSArrayToList on JSArray { - /// Converts this [JSArray] to a [List] by either casting or wrapping it. - /// - /// When compiling to JavaScript, [List]s are [JSArray]s and this will be a - /// cast. When compiling to Wasm, a wrapper is introduced. Modifications to - /// this [JSArray] will affect the [List] and vice versa. In order to ensure - /// type soundness, this method may introduce casts when accessing elements in - /// order to ensure they are of type [T]. - external List get toDart; -} - -/// Conversions from [List] to [JSArray]. -extension ListToJSArray on List { - /// Converts this [List] to a [JSArray] by either casting, unwrapping, or - /// cloning the [List]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, the core [List] is a JavaScript `Array`, - /// > and therefore this method simply casts. User-defined [List]s are - /// > currently unsupported when compiling to JavaScript. - /// > When compiling to Wasm, this [List] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method clones this [List]'s values into a new [JSArray]. - /// > Avoid assuming that modifications to this [List] will affect the - /// > [JSArray] and vice versa unless it was instantiated in JavaScript. - external JSArray get toJS; - - /// Converts this [List] to a [JSArray] by either casting, unwrapping, or - /// proxying the [List]. - /// - /// > [!NOTE] - /// > Depending on whether code is compiled to JavaScript or Wasm, this - /// > conversion will have different semantics. - /// > When compiling to JavaScript, the core [List] is a JavaScript `Array`, - /// > and therefore this method simply casts. User-defined [List]s are - /// > currently unsupported when compiling to JavaScript. - /// > When compiling to Wasm, this [List] may or may not be a wrapper - /// > depending on if it was converted from JavaScript or instantiated in - /// > Dart. If it's a wrapper, this method unwraps it. If it's instantiated in - /// > Dart, this method proxies the [List] using a heavyweight `Array` - /// > wrapper. Access to the original [List]'s elements may be very - /// > unperformant. - /// > Modifications to this [List] will affect the [JSArray] and vice versa. - external JSArray get toJSProxyOrRef; -} - -/// Conversions from [JSNumber] to [double] or [int]. -extension JSNumberToNumber on JSNumber { - /// Converts this [JSNumber] to a [double]. - external double get toDartDouble; - - /// Converts this [JSNumber] to an [int]. - /// - /// If this [JSNumber] is not an integer value, throws. - external int get toDartInt; -} - -/// Conversions from [double] to [JSNumber]. -extension DoubleToJSNumber on double { - /// Converts this [double] to a [JSNumber]. - external JSNumber get toJS; -} - -/// Conversions from [num] to [JSNumber]. -extension NumToJSExtension on num { - /// Converts this [num] to a [JSNumber]. - JSNumber get toJS => DoubleToJSNumber(toDouble()).toJS; -} - -/// Conversions from [JSBoolean] to [bool]. -extension JSBooleanToBool on JSBoolean { - /// Converts this [JSBoolean] to a [bool]. - external bool get toDart; -} - -/// Conversions from [bool] to [JSBoolean]. -extension BoolToJSBoolean on bool { - /// Converts this [bool] to a [JSBoolean]. - external JSBoolean get toJS; -} - -/// Conversions from [JSString] to [String]. -extension JSStringToString on JSString { - /// Converts this [JSString] to a [String]. - external String get toDart; -} - -/// Conversions from [String] to [JSString]. -extension StringToJSString on String { - /// Converts this [String] to a [JSString]. - external JSString get toJS; -} - -/// General-purpose JavaScript operators. -/// -/// Indexing operators (`[]`, `[]=`) should be declared through operator -/// overloading instead like: -/// ``` -/// external operator int [](int key); -/// ``` -/// -/// Operators that always return number or boolean values use the Dart type -/// instead of a JS type for convenience as the conversions are inexpensive. -// TODO(srujzs): Add more as needed. For now, we just expose the ones needed to -// migrate from `dart:js_util`. -extension JSAnyOperatorExtension on JSAny? { - // Arithmetic operators. - - /// The result of [this] + [any] in JavaScript. - external JSAny add(JSAny? any); - - /// The result of [this] - [any] in JavaScript. - external JSAny subtract(JSAny? any); - - /// The result of [this] * [any] in JavaScript. - external JSAny multiply(JSAny? any); - - /// The result of [this] / [any] in JavaScript. - external JSAny divide(JSAny? any); - - /// The result of [this] % [any] in JavaScript. - external JSAny modulo(JSAny? any); - - /// The result of [this] ** [any] in JavaScript. - external JSAny exponentiate(JSAny? any); - - // Comparison operators. - - /// The result of [this] > [any] in JavaScript. - external bool greaterThan(JSAny? any); - - /// The result of [this] >= [any] in JavaScript. - external bool greaterThanOrEqualTo(JSAny? any); - - /// The result of [this] < [any] in JavaScript. - external bool lessThan(JSAny? any); - - /// The result of [this] <= [any] in JavaScript. - external bool lessThanOrEqualTo(JSAny? any); - - /// The result of [this] == [any] in JavaScript. - external bool equals(JSAny? any); - - /// The result of [this] != [any] in JavaScript. - external bool notEquals(JSAny? any); - - /// The result of [this] === [any] in JavaScript. - external bool strictEquals(JSAny? any); - - /// The result of [this] !== [any] in JavaScript. - external bool strictNotEquals(JSAny? any); - - // Bitwise operators. - - /// The result of [this] >>> [any] in JavaScript. - // TODO(srujzs): This should return `num` or `double` instead. - external JSNumber unsignedRightShift(JSAny? any); - - // Logical operators. - - /// The result of [this] && [any] in JavaScript. - external JSAny? and(JSAny? any); - - /// The result of [this] || [any] in JavaScript. - external JSAny? or(JSAny? any); - - /// The result of ![this] in JavaScript. - external bool get not; - - /// The result of !![this] in JavaScript. - external bool get isTruthy; -} - -/// The global scope that is used to find user-declared interop members. -/// -/// For example: -/// -/// ``` -/// @JS() -/// external String get name; -/// ``` -/// -/// Reading `name` will execute JavaScript code like `globalContext.name`. -/// -/// There are subtle differences depending on the compiler, but in general, -/// [globalContext] can be treated like JavaScript's `globalThis`. -external JSObject get globalContext; - -/// Given a instance of a Dart class that contains an @[JSExport] -/// annotation, creates a JavaScript object that wraps the given Dart object. -/// -/// The object literal will be a map of properties, which are either the written -/// instance member names or their renames, to callbacks that call the -/// corresponding Dart instance members. -/// -/// See https://dart.dev/interop/js-interop/mock for more details on how to -/// declare classes that can be used in this method. -external JSObject createJSInteropWrapper(T dartObject); - -// TODO(srujzs): Expose this method when we handle conformance checking for -// interop extension types. We don't expose this method today due to the bound -// on `T`. `@staticInterop` types can't implement `JSObject`, so this method -// simply wouldn't work. We could make it extend `Object` to support the -// `@staticInterop` case, but if we ever refactor to `extends JSObject`, this -// would be a breaking change. For now, due to the low usage of -// `createStaticInteropMock`, we avoid introducing this method until later. -// external T createJSInteropMock( -// U dartMock, [JSObject? proto = null]); - -/// Dynamically imports a JavaScript module with the given [moduleName] using -/// the JavaScript `import()` syntax. -/// -/// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import -/// for more details. -/// -/// Returns a [JSPromise] that resolves to a [JSObject] that's the module -/// namespace object. -external JSPromise importModule(String moduleName); diff --git a/test_files/source/js_interop_unsafe.dart b/test_files/source/js_interop_unsafe.dart deleted file mode 100644 index f5eb186..0000000 --- a/test_files/source/js_interop_unsafe.dart +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -/// Utility methods to manipulate JavaScript objects dynamically. -/// -/// This library is typically meant to be used when the names of properties or -/// methods are not known statically. This library is similar to `dart:js_util`, -/// except the methods here are extension methods that use JS types. This -/// allows code using these functions to also be compiled to WebAssembly. -/// -/// In general, prefer to write JS interop interfaces and external static -/// interop members using `dart:js_interop`. This library is meant to work -/// around issues and help with migration from older JS interop libraries. -/// -/// > [!NOTE] -/// > As the name suggests, usage of this library *can* be unsafe. This means -/// > that safe usage of these methods cannot necessarily be verified -/// > statically. Prefer using statically analyzable values like constants or -/// > literals for property or method names so that usage can be verified. This -/// > library should be used cautiously and only when the same effect cannot be -/// > achieved with static interop. -/// -/// {@category Web} -library; - -import 'dart:js_interop'; - -/// Utility methods to check, get, set, and call properties on a [JSObject]. -/// -/// See the [JavaScript specification](https://tc39.es/ecma262/#sec-object-type) -/// for more details on using properties. -extension JSObjectUnsafeUtilExtension on JSObject { - /// Shorthand helper for [hasProperty] to check whether this [JSObject] - /// contains the property key [property], but takes and returns a Dart value. - bool has(String property) => hasProperty(property.toJS).toDart; - - /// Whether or not this [JSObject] contains the property key [property]. - external JSBoolean hasProperty(JSAny property); - - /// Shorthand helper for [getProperty] to get the value of the property key - /// [property] of this [JSObject], but takes and returns a Dart value. - JSAny? operator [](String property) => getProperty(property.toJS); - - /// The value of the property key [property] of this [JSObject]. - external R getProperty(JSAny property); - - /// Shorthand helper for [setProperty] to write the [value] of the property - /// key [property] of this [JSObject], but takes a Dart value. - void operator []=(String property, JSAny? value) => - setProperty(property.toJS, value); - - /// Write the [value] of property key [property] of this [JSObject]. - external void setProperty(JSAny property, JSAny? value); - - external JSAny? _callMethod(JSAny method, - [JSAny? arg1, JSAny? arg2, JSAny? arg3, JSAny? arg4]); - - /// Calls [method] on this [JSObject] with up to four arguments. - /// - /// Returns the result of calling [method], which must be an [R]. - /// - /// This helper doesn't allow passing nulls, as it determines whether an - /// argument is passed based on whether it was null or not. Prefer - /// [callMethodVarArgs] if you need to pass nulls. - R callMethod(JSAny method, - [JSAny? arg1, JSAny? arg2, JSAny? arg3, JSAny? arg4]) => - _callMethod(method, arg1, arg2, arg3, arg4) as R; - - external JSAny? _callMethodVarArgs(JSAny method, [List? arguments]); - - /// Calls [method] on this [JSObject] with a variable number of [arguments]. - /// - /// Returns the result of calling [method], which must be an [R]. - R callMethodVarArgs(JSAny method, - [List? arguments]) => - _callMethodVarArgs(method, arguments) as R; - - /// Deletes the property with key [property] from this [JSObject]. - external JSBoolean delete(JSAny property); -} - -/// Utility methods to call [JSFunction]s as constructors. -extension JSFunctionUnsafeUtilExtension on JSFunction { - external JSObject _callAsConstructor( - [JSAny? arg1, JSAny? arg2, JSAny? arg3, JSAny? arg4]); - - /// Calls this [JSFunction] as a constructor with up to four arguments. - /// - /// Returns the constructed object, which must be an [R]. - /// - /// This helper doesn't allow passing nulls, as it determines whether an - /// argument is passed based on whether it was null or not. Prefer - /// [callAsConstructorVarArgs] if you need to pass nulls. - // TODO(srujzs): The type bound should extend `JSObject`. - R callAsConstructor( - [JSAny? arg1, JSAny? arg2, JSAny? arg3, JSAny? arg4]) => - _callAsConstructor(arg1, arg2, arg3, arg4) as R; - - external JSObject _callAsConstructorVarArgs([List? arguments]); - - /// Calls this [JSFunction] as a constructor with a variable number of - /// arguments. - /// - /// Returns the constructed [JSObject], which must be an [R]. - R callAsConstructorVarArgs([List? arguments]) => - _callAsConstructorVarArgs(arguments) as R; -} diff --git a/tests/SevenZipTest.php b/tests/SevenZipTest.php index cec2bd4..155591c 100644 --- a/tests/SevenZipTest.php +++ b/tests/SevenZipTest.php @@ -238,7 +238,7 @@ public function testExtract(string $format): void ->target(path: $target) ->extract(); $this->assertFileExists(filename: $target . '/source/Avatart.svg'); - $this->assertFileExists(filename: $target . '/source/js_interop.dart'); + $this->assertFileExists(filename: $target . '/source/js_interop_usage.md'); unlink($archive); }