diff --git a/CHANGELOG.md b/CHANGELOG.md index 839c4355753..9b93514cff4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,20 @@ [#51896]: https://github.com/dart-lang/sdk/issues/51896 +#### `dart:js_interop` + +- **Breaking Change in the representation of JS types** [#52687][]: JS types + like `JSAny` were previously represented using a custom erasure of + `@staticInterop` types that were compiler-specific. They are now represented + as extension types where their representation types are compiler-specific. + This means that user-defined `@staticInterop` types that implemented `JSAny` + or `JSObject` can no longer do so and need to use + `JSObject.fromInteropObject`. Going forward, it's recommended to use extension + types to define interop APIs. Those extension types can still implement JS + types. + +[#52687]: https://github.com/dart-lang/sdk/issues/52687 + #### `dart:typed_data` - **BREAKING CHANGE** (https://github.com/dart-lang/sdk/issues/53218) The diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart index 3d51157f0b6..b5a7f59808f 100644 --- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart +++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart @@ -9123,39 +9123,6 @@ Message _withArgumentsJsInteropStaticInteropWithInstanceMembers(String name) { arguments: {'name': name}); } -// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. -const Template - templateJsInteropStaticInteropWithInvalidJsTypesSupertype = - const Template( - "JsInteropStaticInteropWithInvalidJsTypesSupertype", - problemMessageTemplate: - r"""`@staticInterop` class '#name' cannot have '#name2' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes.""", - correctionMessageTemplate: - r"""Try subtyping `JSObject` or `JSAny` instead, or try casting an object of type '#name' to '#name2' when needed.""", - withArguments: - _withArgumentsJsInteropStaticInteropWithInvalidJsTypesSupertype); - -// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. -const Code - codeJsInteropStaticInteropWithInvalidJsTypesSupertype = - const Code( - "JsInteropStaticInteropWithInvalidJsTypesSupertype", -); - -// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. -Message _withArgumentsJsInteropStaticInteropWithInvalidJsTypesSupertype( - String name, String name2) { - if (name.isEmpty) throw 'No name provided'; - name = demangleMixinApplicationName(name); - if (name2.isEmpty) throw 'No name provided'; - name2 = demangleMixinApplicationName(name2); - return new Message(codeJsInteropStaticInteropWithInvalidJsTypesSupertype, - problemMessage: - """`@staticInterop` class '${name}' cannot have '${name2}' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes.""", - correctionMessage: """Try subtyping `JSObject` or `JSAny` instead, or try casting an object of type '${name}' to '${name2}' when needed.""", - arguments: {'name': name, 'name2': name2}); -} - // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Template templateJsInteropStaticInteropWithNonStaticSupertype = diff --git a/pkg/_js_interop_checks/lib/js_interop_checks.dart b/pkg/_js_interop_checks/lib/js_interop_checks.dart index 1beedea63ae..3005f22be27 100644 --- a/pkg/_js_interop_checks/lib/js_interop_checks.dart +++ b/pkg/_js_interop_checks/lib/js_interop_checks.dart @@ -31,7 +31,6 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart' templateJsInteropNonStaticWithStaticInteropSupertype, templateJsInteropStaticInteropNoJSAnnotation, templateJsInteropStaticInteropWithInstanceMembers, - templateJsInteropStaticInteropWithInvalidJsTypesSupertype, templateJsInteropStaticInteropWithNonStaticSupertype, templateJsInteropObjectLiteralConstructorPositionalParameters, templateJsInteropNativeClassInAnnotation, @@ -227,13 +226,17 @@ class JsInteropChecks extends RecursiveVisitor { report(templateJsInteropStaticInteropNoJSAnnotation .withArguments(node.name)); } - if (superclass != null) { - _checkSuperclassOfStaticInteropClass(node, superclass); + if (superclass != null && !hasStaticInteropAnnotation(superclass)) { + report(templateJsInteropStaticInteropWithNonStaticSupertype + .withArguments(node.name, superclass.name)); } // Validate that superinterfaces are all valid supertypes as well. Note // that mixins are already disallowed and therefore are not checked here. for (final supertype in node.implementedTypes) { - _checkSuperclassOfStaticInteropClass(node, supertype.classNode); + if (!hasStaticInteropAnnotation(supertype.classNode)) { + report(templateJsInteropStaticInteropWithNonStaticSupertype + .withArguments(node.name, supertype.classNode.name)); + } } } else { // For classes, `dart:js_interop`'s `@JS` can only be used with @@ -819,39 +822,6 @@ class JsInteropChecks extends RecursiveVisitor { } } - /// Reports an error if @staticInterop classes extends or implements a - /// non-@staticInterop type or an invalid dart:_js_types type. - void _checkSuperclassOfStaticInteropClass(Class node, Class superclass) { - void report(Message message) => _reporter.report( - message, node.fileOffset, node.name.length, node.fileUri); - if (!hasStaticInteropAnnotation(superclass)) { - report(templateJsInteropStaticInteropWithNonStaticSupertype.withArguments( - node.name, superclass.name)); - } else { - // dart:_js_types @staticInterop types are special. They are custom-erased - // to different types at runtime. User @staticInterop types are always - // erased to JavaScriptObject. As such, this means that we should only - // allow users to subtype dart:_js_types types that erase to a - // T >: JavaScriptObject. Currently, this is only JSObject and JSAny. - // TODO(srujzs): This error should be temporary. In the future, once we - // have extension types that can implement concrete classes, we can move - // all the dart:_js_types that aren't JSObject and JSAny to extension - // types. Then, this error becomes redundant. This would also allow us to - // idiomatically add type parameters to JSArray and JSPromise. - final superclassUri = superclass.enclosingLibrary.importUri; - // Make an exception for some internal libraries. - final allowList = {'_js_types', '_js_helper'}; - if (superclassUri.isScheme('dart') && - superclassUri.path == '_js_types' && - !allowList.contains(node.enclosingLibrary.importUri.path) && - superclass.name != 'JSAny' && - superclass.name != 'JSObject') { - report(templateJsInteropStaticInteropWithInvalidJsTypesSupertype - .withArguments(node.name, superclass.name)); - } - } - } - /// If [procedure] is a generated procedure that represents a relevant /// tear-off, return the torn-off member. /// @@ -944,9 +914,6 @@ class JsInteropChecks extends RecursiveVisitor { .isInteropExtensionType(type.extensionTypeDeclaration)) { return true; } - // Extension types where the representation type is allowed are okay. - // TODO(srujzs): Once the CFE pre-computes the concrete type, don't - // recurse. return _isAllowedExternalType(type.extensionTypeErasure); } return false; 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 316bd1944f8..989b3e4de54 100644 --- a/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart +++ b/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart @@ -28,8 +28,8 @@ class ExportCreator extends Transformer { final Procedure _functionToJS; final Procedure _getProperty; final Procedure _globalContext; - final Class _jsAny; - final Class _jsObject; + final ExtensionTypeDeclaration _jsAny; + final ExtensionTypeDeclaration _jsObject; final Procedure _setProperty; final Procedure _stringToJS; final StaticInteropMockValidator _staticInteropMockValidator; @@ -51,9 +51,9 @@ class ExportCreator extends Transformer { _globalContext = _typeEnvironment.coreTypes.index .getTopLevelProcedure('dart:js_interop', 'get:globalContext'), _jsAny = _typeEnvironment.coreTypes.index - .getClass('dart:_js_types', 'JSAny'), + .getExtensionType('dart:js_interop', 'JSAny'), _jsObject = _typeEnvironment.coreTypes.index - .getClass('dart:_js_types', 'JSObject'), + .getExtensionType('dart:js_interop', 'JSObject'), _setProperty = _typeEnvironment.coreTypes.index.getTopLevelProcedure( 'dart:js_interop_unsafe', 'JSObjectUnsafeUtilExtension|[]='), _stringToJS = _typeEnvironment.coreTypes.index.getTopLevelProcedure( @@ -175,7 +175,7 @@ class ExportCreator extends Transformer { Expression asJSObject(Expression object, [bool nullable = false]) => AsExpression( object, - InterfaceType(_jsObject, + ExtensionType(_jsObject, nullable ? Nullability.nullable : Nullability.nonNullable)) ..fileOffset = node.fileOffset; @@ -192,7 +192,7 @@ class ExportCreator extends Transformer { jsObject, toJSString(methodName), ListLiteral(args, - typeArgument: InterfaceType(_jsAny, Nullability.nullable)) + typeArgument: ExtensionType(_jsAny, Nullability.nullable)) ], types: [ returnType ])) @@ -211,7 +211,7 @@ class ExportCreator extends Transformer { getObjectProperty(), 'create', [asJSObject(proto ?? NullLiteral(), true)], - InterfaceType(_jsObject, Nullability.nonNullable)); + ExtensionType(_jsObject, Nullability.nonNullable)); } var exportMap = @@ -230,7 +230,7 @@ class ExportCreator extends Transformer { var jsExporter = VariableDeclaration('#jsExporter', initializer: getLiteral(proto), - type: InterfaceType(_jsObject, Nullability.nonNullable), + type: ExtensionType(_jsObject, Nullability.nonNullable), isSynthesized: true) ..fileOffset = node.fileOffset ..parent = node.parent; @@ -295,7 +295,7 @@ class ExportCreator extends Transformer { // statements for each export name. var getSetMap = VariableDeclaration('#${exportName}Mapping', initializer: getLiteral(), - type: InterfaceType(_jsObject, Nullability.nonNullable), + type: ExtensionType(_jsObject, Nullability.nonNullable), isSynthesized: true) ..fileOffset = node.fileOffset ..parent = node.parent; diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart index 9e8fe9669c8..06d451cd48a 100644 --- a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart +++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart @@ -786,23 +786,27 @@ class ExtensionIndex { /// /// This currently allows the interface type to be: /// - all package:js classes - /// - dart:js_types types + /// - dart:js_interop types /// - @Native types that implement JavaScriptObject + /// - extension types that wrap any of the above bool isInteropExtensionType(ExtensionTypeDeclaration extensionType) { final reference = extensionType.reference; if (_interopExtensionTypeIndex.containsKey(reference)) { return _interopExtensionTypeIndex[reference]!; } - DartType repType = extensionType.declaredRepresentationType; - if (repType is ExtensionType) { - repType = repType.extensionTypeErasure; + // Check if this is an dart:js_interop JS type or recursively an extension + // type on one. + DartType repType = ExtensionType(extensionType, Nullability.nonNullable); + while (repType is ExtensionType) { + final declaration = repType.extensionTypeDeclaration; + if (declaration.enclosingLibrary.importUri.toString() == + 'dart:js_interop') { + return true; + } + repType = declaration.declaredRepresentationType; } if (repType is InterfaceType) { final cls = repType.classNode; - // TODO(srujzs): Note that dart:_js_types types currently use a custom - // lowering of @staticInterop. Once - // https://github.com/dart-lang/sdk/issues/52687 is handled, we should - // modify this if-check to handle the new representation. final javaScriptObject = _coreTypes.index .tryGetClass('dart:_interceptors', 'JavaScriptObject'); if (hasStaticInteropAnnotation(cls) || diff --git a/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart b/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart index b65a26bdba2..187a4e409a1 100644 --- a/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart +++ b/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart @@ -13,112 +13,11 @@ import 'package:kernel/src/constant_replacer.dart'; import 'package:kernel/src/replacement_visitor.dart'; /// Erasure function for `@staticInterop` types for the JS compilers. -/// -/// `dart:_js_types` are implemented currently using `@staticInterop`, but they -/// are erased to different types at runtime. Non-`dart:_js_types` -/// `@staticInterop` types are erased to `JavaScriptObject`. InterfaceType eraseStaticInteropTypesForJSCompilers( - CoreTypes coreTypes, InterfaceType staticInteropType) { - if (staticInteropType.classNode.enclosingLibrary.importUri == - Uri.parse('dart:_js_types')) { - final className = staticInteropType.classNode.name; - Class erasedClass; - var typeArguments = staticInteropType.typeArguments; - // TODO(srujzs): Switch to a switch expression once they're working in the - // SDK. - switch (className) { - case 'JSAny': - erasedClass = coreTypes.objectClass; - break; - case 'JSObject': - erasedClass = - coreTypes.index.getClass('dart:_interceptors', 'JSObject'); - break; - case 'JSFunction': - erasedClass = coreTypes.functionClass; - break; - case 'JSExportedDartFunction': - erasedClass = coreTypes.functionClass; - break; - case 'JSArray': - erasedClass = coreTypes.listClass; - typeArguments = [coreTypes.objectNullableRawType]; - break; - case 'JSBoxedDartObject': - erasedClass = - coreTypes.index.getClass('dart:_interceptors', 'JSObject'); - break; - case 'JSArrayBuffer': - erasedClass = coreTypes.index.getClass('dart:typed_data', 'ByteBuffer'); - break; - case 'JSDataView': - erasedClass = coreTypes.index.getClass('dart:typed_data', 'ByteData'); - break; - case 'JSTypedArray': - erasedClass = coreTypes.index.getClass('dart:typed_data', 'TypedData'); - break; - case 'JSInt8Array': - erasedClass = coreTypes.index.getClass('dart:typed_data', 'Int8List'); - break; - case 'JSUint8Array': - erasedClass = coreTypes.index.getClass('dart:typed_data', 'Uint8List'); - break; - case 'JSUint8ClampedArray': - erasedClass = - coreTypes.index.getClass('dart:typed_data', 'Uint8ClampedList'); - break; - case 'JSInt16Array': - erasedClass = coreTypes.index.getClass('dart:typed_data', 'Int16List'); - break; - case 'JSUint16Array': - erasedClass = coreTypes.index.getClass('dart:typed_data', 'Uint16List'); - break; - case 'JSInt32Array': - erasedClass = coreTypes.index.getClass('dart:typed_data', 'Int32List'); - break; - case 'JSUint32Array': - erasedClass = coreTypes.index.getClass('dart:typed_data', 'Uint32List'); - break; - case 'JSFloat32Array': - erasedClass = - coreTypes.index.getClass('dart:typed_data', 'Float32List'); - break; - case 'JSFloat64Array': - erasedClass = - coreTypes.index.getClass('dart:typed_data', 'Float64List'); - break; - case 'JSNumber': - erasedClass = coreTypes.doubleClass; - break; - case 'JSBoolean': - erasedClass = coreTypes.boolClass; - break; - case 'JSString': - erasedClass = coreTypes.stringClass; - break; - case 'JSPromise': - erasedClass = - coreTypes.index.getClass('dart:_interceptors', 'JSObject'); - break; - case 'JSSymbol': - erasedClass = - coreTypes.index.getClass('dart:_interceptors', 'JavaScriptSymbol'); - break; - case 'JSBigInt': - erasedClass = - coreTypes.index.getClass('dart:_interceptors', 'JavaScriptBigInt'); - break; - default: - throw 'Unimplemented `dart:_js_types`: $className'; - } - return InterfaceType( - erasedClass, staticInteropType.declaredNullability, typeArguments); - } else { - return InterfaceType( + CoreTypes coreTypes, InterfaceType staticInteropType) => + InterfaceType( coreTypes.index.getClass('dart:_interceptors', 'JavaScriptObject'), staticInteropType.declaredNullability); - } -} class _TypeSubstitutor extends ReplacementVisitor { final InterfaceType Function(InterfaceType staticInteropType) diff --git a/pkg/compiler/lib/src/phase/load_kernel.dart b/pkg/compiler/lib/src/phase/load_kernel.dart index 1c1ad5a2222..14c5fb3d3c2 100644 --- a/pkg/compiler/lib/src/phase/load_kernel.dart +++ b/pkg/compiler/lib/src/phase/load_kernel.dart @@ -168,9 +168,7 @@ void _doTransformsOnKernelLoad( evaluationMode: options.useLegacySubtyping ? fe.EvaluationMode.weak : fe.EvaluationMode.strong); - StaticInteropClassEraser(coreTypes, - additionalCoreLibraries: {'_js_types', 'js_interop'}) - .visitComponent(component); + StaticInteropClassEraser(coreTypes).visitComponent(component); globalTransforms.transformLibraries( component.libraries, constantsEvaluator, coreTypes, options); _simplifyConstConditionals(component, options, classHierarchy, reporter); diff --git a/pkg/compiler/test/impact/data/jsinterop.dart b/pkg/compiler/test/impact/data/jsinterop.dart index b862598bddb..ddd2b24eb01 100644 --- a/pkg/compiler/test/impact/data/jsinterop.dart +++ b/pkg/compiler/test/impact/data/jsinterop.dart @@ -32,30 +32,6 @@ class JsInteropClass { /*member: JsInteropClass.method:type=[ native:GenericClass, - native:JSAny, - native:JSArray, - native:JSArrayBuffer, - native:JSBigInt, - native:JSBoolean, - native:JSBoxedDartObject, - native:JSDataView, - native:JSExportedDartFunction, - native:JSFloat32Array, - native:JSFloat64Array, - native:JSFunction, - native:JSInt16Array, - native:JSInt32Array, - native:JSInt8Array, - native:JSNumber, - native:JSObject, - native:JSPromise, - native:JSString, - native:JSSymbol, - native:JSTypedArray, - native:JSUint16Array, - native:JSUint32Array, - native:JSUint8Array, - native:JSUint8ClampedArray, native:JsInteropClass]*/ @JS() external double method(); diff --git a/pkg/compiler/test/impact/data/jsinterop_setter1.dart b/pkg/compiler/test/impact/data/jsinterop_setter1.dart index a9f4b62bab9..eb917cb6a2f 100644 --- a/pkg/compiler/test/impact/data/jsinterop_setter1.dart +++ b/pkg/compiler/test/impact/data/jsinterop_setter1.dart @@ -55,30 +55,6 @@ import 'package:js/js.dart'; native:DomError, native:DomException, native:ErrorEvent, - native:JSAny, - native:JSArray, - native:JSArrayBuffer, - native:JSBigInt, - native:JSBoolean, - native:JSBoxedDartObject, - native:JSDataView, - native:JSExportedDartFunction, - native:JSFloat32Array, - native:JSFloat64Array, - native:JSFunction, - native:JSInt16Array, - native:JSInt32Array, - native:JSInt8Array, - native:JSNumber, - native:JSObject, - native:JSPromise, - native:JSString, - native:JSSymbol, - native:JSTypedArray, - native:JSUint16Array, - native:JSUint32Array, - native:JSUint8Array, - native:JSUint8ClampedArray, native:MediaError, native:NavigatorUserMediaError, native:OverconstrainedError, diff --git a/pkg/compiler/test/impact/data/jsinterop_setter2.dart b/pkg/compiler/test/impact/data/jsinterop_setter2.dart index 4d6831879be..7f5b60ba380 100644 --- a/pkg/compiler/test/impact/data/jsinterop_setter2.dart +++ b/pkg/compiler/test/impact/data/jsinterop_setter2.dart @@ -62,30 +62,6 @@ import 'package:js/js.dart'; native:DomException, native:ErrorEvent, native:File, - native:JSAny, - native:JSArray, - native:JSArrayBuffer, - native:JSBigInt, - native:JSBoolean, - native:JSBoxedDartObject, - native:JSDataView, - native:JSExportedDartFunction, - native:JSFloat32Array, - native:JSFloat64Array, - native:JSFunction, - native:JSInt16Array, - native:JSInt32Array, - native:JSInt8Array, - native:JSNumber, - native:JSObject, - native:JSPromise, - native:JSString, - native:JSSymbol, - native:JSTypedArray, - native:JSUint16Array, - native:JSUint32Array, - native:JSUint8Array, - native:JSUint8ClampedArray, native:MediaError, native:NavigatorUserMediaError, native:OverconstrainedError, diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status index 6703fcb423f..5ffd9167615 100644 --- a/pkg/front_end/messages.status +++ b/pkg/front_end/messages.status @@ -677,8 +677,6 @@ JsInteropStaticInteropTrustTypesUsedWithoutStaticInterop/analyzerCode: Fail # We JsInteropStaticInteropTrustTypesUsedWithoutStaticInterop/example: Fail # Web compiler specific JsInteropStaticInteropWithInstanceMembers/analyzerCode: Fail # Web compiler specific JsInteropStaticInteropWithInstanceMembers/example: Fail # Web compiler specific -JsInteropStaticInteropWithInvalidJsTypesSupertype/analyzerCode: Fail # Web compiler specific -JsInteropStaticInteropWithInvalidJsTypesSupertype/example: Fail # Web compiler specific JsInteropStaticInteropWithNonStaticSupertype/analyzerCode: Fail # Web compiler specific JsInteropStaticInteropWithNonStaticSupertype/example: Fail # Web compiler specific JsInteropStrictModeForbiddenLibrary/analyzerCode: Fail # Web compiler specific diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index f68081779a9..c038016b611 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -5889,10 +5889,6 @@ JsInteropStaticInteropWithInstanceMembers: problemMessage: "JS interop class '#name' with `@staticInterop` annotation cannot declare instance members." correctionMessage: "Try moving the instance member to a static extension." -JsInteropStaticInteropWithInvalidJsTypesSupertype: - problemMessage: "`@staticInterop` class '#name' cannot have '#name2' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes." - correctionMessage: "Try subtyping `JSObject` or `JSAny` instead, or try casting an object of type '#name' to '#name2' when needed." - JsInteropStaticInteropWithNonStaticSupertype: problemMessage: "JS interop class '#name' has an `@staticInterop` annotation, but has supertype '#name2', which does not." correctionMessage: "Try marking the supertype as a static interop class using `@staticInterop`." 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 99cab9dbe41..5a755c5ce5c 100644 --- a/sdk/lib/_internal/js_shared/lib/js_interop_patch.dart +++ b/sdk/lib/_internal/js_shared/lib/js_interop_patch.dart @@ -5,11 +5,16 @@ 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_helper' show createObjectLiteral, staticInteropGlobalContext; import 'dart:_js_types'; +import 'dart:js_interop'; import 'dart:js_util' as js_util; import 'dart:typed_data'; +@patch +JSObjectRepType _createObjectLiteral() => + createObjectLiteral(); + @patch @pragma('dart2js:prefer-inline') JSObject get globalContext => staticInteropGlobalContext as JSObject; diff --git a/sdk/lib/_internal/js_shared/lib/js_types.dart b/sdk/lib/_internal/js_shared/lib/js_types.dart index 07a0c92a162..14f4c5b7cc1 100644 --- a/sdk/lib/_internal/js_shared/lib/js_types.dart +++ b/sdk/lib/_internal/js_shared/lib/js_types.dart @@ -8,138 +8,70 @@ /// /// For consistency, all of the web backends have a version of this library. /// -/// For the time being, all JS types are erased to their respective Dart type at -/// runtime e.g. [JSString] -> [String]. Eventually, when we have inline -/// classes, we may choose to either: -/// -/// 1. Use [Object] as the representation type. -/// 2. Have some analog to dart2wasm's [JSValue] as the representation type in -/// order to separate the Dart and JS type hierarchies at runtime. -/// 3. Continue using the respective Dart type. -/// -/// Note that we can't use [Interceptor] to do option #2. [Interceptor] is a -/// supertype of types like [interceptors.JSString], but not a supertype of the -/// core types like [String]. This becomes relevant when we use external APIs. -/// External APIs get lowered to `js_util` calls, which cast the return value. -/// If a function returns a JavaScript string, it gets reified as a Dart -/// [String] for example. Then when we cast to [JSString] in `js_util`, we get -/// a cast failure, as [String] is not a subtype of [Interceptor]. -/// -/// For specific details of the JS type hierarchy, please see -/// `sdk/lib/js_interop/js_interop.dart`. +/// **WARNING**: You should *not* rely on these runtime types. Not only is this +/// library not guaranteed to be consistent across platforms, these types may +/// change in the future. library _js_types; -import 'dart:_js_annotations'; -import 'dart:_js_helper' show createObjectLiteral; +import 'dart:_native_typed_data' as typed_data; +import 'dart:_interceptors' as interceptors; -@JS() -@staticInterop -class JSAny { - // Unnamed factory constructor so users can only implement JSAny. - external factory JSAny._(); -} +typedef JSAnyRepType = Object; -@JS() -@staticInterop -class JSObject implements JSAny { - /// Returns a new object literal. - factory JSObject() => createObjectLiteral(); -} +typedef JSObjectRepType = interceptors.JSObject; -@JS() -@staticInterop -class JSFunction implements JSObject {} +// TODO(srujzs): The JS function types have to be typed as +// `LegacyJavaScriptObject` for now until we reify JS functions as +// `JavaScriptFunction` instead of `LegacyJavaScriptObject` in DDC. This will +// happen with the new RTI. Note that we *cannot* make this `Function`, even +// though all JS functions are Dart functions in our type system, because +// `Function` is not <: `JSObject`. This subtyping relationship is required for +// `dart:js_interop`'s extension types. +typedef JSFunctionRepType = interceptors.LegacyJavaScriptObject; -@JS() -@staticInterop -class JSExportedDartFunction implements JSFunction {} +typedef JSExportedDartFunctionRepType = interceptors.LegacyJavaScriptObject; -@JS('Array') -@staticInterop -class JSArray implements JSObject { - external factory JSArray(); - external factory JSArray.withLength(int length); -} +typedef JSArrayRepType = interceptors.JSArray; -@JS() -@staticInterop -class JSBoxedDartObject implements JSObject {} +typedef JSBoxedDartObjectRepType = interceptors.JSObject; -@JS() -@staticInterop -class JSArrayBuffer implements JSObject {} +typedef JSArrayBufferRepType = typed_data.NativeByteBuffer; -@JS() -@staticInterop -class JSDataView implements JSObject {} +typedef JSDataViewRepType = typed_data.NativeByteData; -@JS() -@staticInterop -class JSTypedArray implements JSObject {} +typedef JSTypedArrayRepType = typed_data.NativeTypedData; -@JS() -@staticInterop -class JSInt8Array implements JSTypedArray {} +typedef JSInt8ArrayRepType = typed_data.NativeInt8List; -@JS() -@staticInterop -class JSUint8Array implements JSTypedArray {} +typedef JSUint8ArrayRepType = typed_data.NativeUint8List; -@JS() -@staticInterop -class JSUint8ClampedArray implements JSTypedArray {} +typedef JSUint8ClampedArrayRepType = typed_data.NativeUint8ClampedList; -@JS() -@staticInterop -class JSInt16Array implements JSTypedArray {} +typedef JSInt16ArrayRepType = typed_data.NativeInt16List; -@JS() -@staticInterop -class JSUint16Array implements JSTypedArray {} +typedef JSUint16ArrayRepType = typed_data.NativeUint16List; -@JS() -@staticInterop -class JSInt32Array implements JSTypedArray {} +typedef JSInt32ArrayRepType = typed_data.NativeInt32List; -@JS() -@staticInterop -class JSUint32Array implements JSTypedArray {} +typedef JSUint32ArrayRepType = typed_data.NativeUint32List; -@JS() -@staticInterop -class JSFloat32Array implements JSTypedArray {} +typedef JSFloat32ArrayRepType = typed_data.NativeFloat32List; -@JS() -@staticInterop -class JSFloat64Array implements JSTypedArray {} +typedef JSFloat64ArrayRepType = typed_data.NativeFloat64List; -@JS() -@staticInterop -class JSNumber implements JSAny {} +typedef JSNumberRepType = double; -@JS() -@staticInterop -class JSBoolean implements JSAny {} +typedef JSBooleanRepType = bool; -@JS() -@staticInterop -class JSString implements JSAny {} +typedef JSStringRepType = String; -@JS() -@staticInterop -class JSSymbol implements JSAny {} +typedef JSPromiseRepType = interceptors.JSObject; -@JS() -@staticInterop -class JSBigInt implements JSAny {} +typedef JSSymbolRepType = interceptors.JavaScriptSymbol; + +typedef JSBigIntRepType = interceptors.JavaScriptBigInt; /// [JSVoid] is just a typedef for [void]. While we could just use /// `JSUndefined`, in the future we may be able to use this to elide `return`s /// in JS trampolines. -typedef JSVoid = void; - -@JS('Promise') -@staticInterop -class JSPromise implements JSObject { - external factory JSPromise(JSFunction executor); -} +typedef JSVoidRepType = void; diff --git a/sdk/lib/_internal/wasm/lib/js_interop_patch.dart b/sdk/lib/_internal/wasm/lib/js_interop_patch.dart index dcaad358d00..69503a5eee0 100644 --- a/sdk/lib/_internal/wasm/lib/js_interop_patch.dart +++ b/sdk/lib/_internal/wasm/lib/js_interop_patch.dart @@ -18,6 +18,10 @@ import 'dart:typed_data'; /// TODO(joshualitt): Find a way to get rid of the explicit casts. T _box(WasmExternRef? ref) => JSValue(ref) as T; +@patch +js_types.JSObjectRepType _createObjectLiteral() => + _box(js_helper.newObjectRaw()); + // This should match the global context we use in our static interop lowerings. @patch JSObject get globalContext => js_util.globalThis as JSObject; diff --git a/sdk/lib/_internal/wasm/lib/js_string_convert.dart b/sdk/lib/_internal/wasm/lib/js_string_convert.dart index 9ab633dca4d..062b7339512 100644 --- a/sdk/lib/_internal/wasm/lib/js_string_convert.dart +++ b/sdk/lib/_internal/wasm/lib/js_string_convert.dart @@ -5,9 +5,10 @@ /// `dart:convert` UTF-8 decoding functions when the input is a JS typed array. library dart._js_string_convert; -import "dart:_js_types"; import 'dart:_js_helper' as js; +import 'dart:_js_types'; import 'dart:_wasm'; +import 'dart:js_interop'; /// Implements `_Utf8Decoder.convertSingle` hook for JS array inputs. Does not /// do bounds checking. diff --git a/sdk/lib/_internal/wasm/lib/js_types.dart b/sdk/lib/_internal/wasm/lib/js_types.dart index 1a7a2faf139..64d66d61aae 100644 --- a/sdk/lib/_internal/wasm/lib/js_types.dart +++ b/sdk/lib/_internal/wasm/lib/js_types.dart @@ -4,8 +4,13 @@ /// This library exists to act as a uniform abstraction layer between the user /// facing JS interop libraries and backend specific internal representations of -/// JS types. For consistency, all of the web backends have a version of this -/// library. +/// JS types. +/// +/// For consistency, all of the web backends have a version of this library. +/// +/// **WARNING**: You should *not* rely on these runtime types. Not only is this +/// library not guaranteed to be consistent across platforms, these types may +/// change in the future. library dart._js_types; import 'dart:_internal'; @@ -21,154 +26,55 @@ part 'js_array.dart'; part 'js_string.dart'; part 'js_typed_array.dart'; -/// Note that the semantics of JS types on Wasm backends are slightly different -/// from the JS backends. They all use `@staticInterop` currently, but Wasm -/// erases to [JSValue], while the JS backends erase each JS type to its -/// respective Dart type. -/// -/// Because we're not sure exactly where things will end up, we're moving -/// gradually towards consistent semantics across all web backends. A gradual -/// path to consistent semantics might look something like: -/// 1) Launch MVP with JS backends conflating Dart types and JS types, and Wasm -/// backends implementing JS types with boxes. On Wasm backends, users will -/// have to explicitly coerce Dart types to JS types, possibly with some -/// overhead, whereas on JS backends users will get coercion for free. This -/// will enable some level of API sharing, without any additional performance -/// overhead on all backends. -/// 2) Introduce a flag for JS backends to support statically decoupling JS -/// types and Dart types on JS backends, while still allowing runtime -/// conflation. This will require users on JS backends to explicitly coerce -/// Dart types to JS types, but will not introduce additional runtime -/// overhead. -/// 3) Introduce a flag for JS backends to fully decouple JS types from Dart -/// types using boxes. However, we will be able to elide boxes on all -/// backends in many cases, except when JS types are upcast to [Object]. -/// TODO(joshualitt): A number of issues are still TBD: -/// 1) Today Wasm backends must copy JS arrays to Dart [List]s and vice versa. -/// To match semantics, we have a few options. -/// a) Copy on JS backends, this will introduce overhead, but users can -/// always leave JS types as JS types to avoid the overhead. -/// b) Experiment with proxying. While we can proxy on the Dart side of the -/// interop boundary, we may not be able to do so on the JS side, and even -/// if we can it will involve considerable overhead and may be observable. -/// Furthermore, 'live' [List]s backed by native JS objects can be quite -/// confusing to users. -/// 2) There are many open questions around how to handle JSNull and -/// JSUndefined. For efficiency reasons, these are currently conflated on JS -/// backends, but this is not efficient on Wasm backends. We may encourage a -/// set of best practices, while allowing some divergence in behavior between -/// JS and Wasm backends until we have a better story here. -@JS() -@staticInterop -class JSAny { - // Unnamed factory constructor so users can only implement JSAny. - external factory JSAny._(); -} +typedef JSAnyRepType = js.JSValue; -@JS('Object') -@staticInterop -class JSObject implements JSAny { - /// Returns a new object literal. - factory JSObject() => js.JSValue(js.newObjectRaw()) as JSObject; +typedef JSObjectRepType = js.JSValue; - /// Equivalent to `Object.keys(object)`. - external static JSArray keys(JSObject o); -} +typedef JSFunctionRepType = js.JSValue; -@JS() -@staticInterop -class JSFunction implements JSObject {} +typedef JSExportedDartFunctionRepType = js.JSValue; -@JS() -@staticInterop -class JSExportedDartFunction implements JSFunction {} +typedef JSArrayRepType = js.JSValue; -@JS('Promise') -@staticInterop -class JSPromise implements JSObject { - external factory JSPromise(JSFunction executor); -} +typedef JSBoxedDartObjectRepType = js.JSValue; -@JS('Array') -@staticInterop -class JSArray implements JSObject { - external factory JSArray(); - external factory JSArray.withLength(int length); -} +typedef JSArrayBufferRepType = js.JSValue; -@JS() -@staticInterop -class JSBoxedDartObject implements JSObject {} +typedef JSDataViewRepType = js.JSValue; -@JS() -@staticInterop -class JSArrayBuffer implements JSObject {} +typedef JSTypedArrayRepType = js.JSValue; -@JS() -@staticInterop -class JSDataView implements JSObject {} +typedef JSInt8ArrayRepType = js.JSValue; -@JS() -@staticInterop -class JSTypedArray implements JSObject {} +typedef JSUint8ArrayRepType = js.JSValue; -@JS() -@staticInterop -class JSInt8Array implements JSTypedArray {} +typedef JSUint8ClampedArrayRepType = js.JSValue; -@JS() -@staticInterop -class JSUint8Array implements JSTypedArray {} +typedef JSInt16ArrayRepType = js.JSValue; -@JS() -@staticInterop -class JSUint8ClampedArray implements JSTypedArray {} +typedef JSUint16ArrayRepType = js.JSValue; -@JS() -@staticInterop -class JSInt16Array implements JSTypedArray {} +typedef JSInt32ArrayRepType = js.JSValue; -@JS() -@staticInterop -class JSUint16Array implements JSTypedArray {} +typedef JSUint32ArrayRepType = js.JSValue; -@JS() -@staticInterop -class JSInt32Array implements JSTypedArray {} +typedef JSFloat32ArrayRepType = js.JSValue; -@JS() -@staticInterop -class JSUint32Array implements JSTypedArray {} +typedef JSFloat64ArrayRepType = js.JSValue; -@JS() -@staticInterop -class JSFloat32Array implements JSTypedArray {} +typedef JSNumberRepType = js.JSValue; -@JS() -@staticInterop -class JSFloat64Array implements JSTypedArray {} +typedef JSBooleanRepType = js.JSValue; -@JS() -@staticInterop -class JSNumber implements JSAny {} +typedef JSStringRepType = js.JSValue; -@JS() -@staticInterop -class JSBoolean implements JSAny {} +typedef JSPromiseRepType = js.JSValue; -@JS() -@staticInterop -class JSString implements JSAny {} +typedef JSSymbolRepType = js.JSValue; -@JS() -@staticInterop -class JSSymbol implements JSAny {} - -@JS() -@staticInterop -class JSBigInt implements JSAny {} +typedef JSBigIntRepType = js.JSValue; /// [JSVoid] is just a typedef for [void]. While we could just use /// `JSUndefined`, in the future we may be able to use this to elide `return`s /// in JS trampolines. -typedef JSVoid = void; +typedef JSVoidRepType = void; diff --git a/sdk/lib/_internal/wasm/lib/regexp_helper.dart b/sdk/lib/_internal/wasm/lib/regexp_helper.dart index 3f2e54882a7..ea9a6b7768f 100644 --- a/sdk/lib/_internal/wasm/lib/regexp_helper.dart +++ b/sdk/lib/_internal/wasm/lib/regexp_helper.dart @@ -21,9 +21,15 @@ String quoteStringForRegExp(String string) => return stringToDartString(jsString); }""", string); +// TODO(srujzs): Add this to `JSObject`. +@js.JS('Object.keys') +external JSArray objectKeys(JSObject o); + +// TODO(srujzs): Convert these to extension types and have `JSNativeMatch` +// subtype `JSArray`. @js.JS() @js.staticInterop -class JSNativeMatch extends JSArray { +class JSNativeMatch { // This constructor exists just to avoid the `no unnamed constructor` error. external factory JSNativeMatch(); } @@ -33,6 +39,8 @@ extension JSNativeMatchExtension on JSNativeMatch { external JSNumber get index; external JSObject? get groups; external JSNumber get length; + external JSAny? pop(); + external JSAny? operator [](JSNumber index); } @js.JS() @@ -115,8 +123,7 @@ class JSSyntaxRegExp implements RegExp { RegExpMatch? firstMatch(String string) { JSNativeMatch? m = _nativeRegExp.exec(string.toJS); - if (m.isUndefinedOrNull) return null; - return new _MatchImplementation(this, m!); + return m == null ? null : new _MatchImplementation(this, m); } bool hasMatch(String string) { @@ -140,18 +147,17 @@ class JSSyntaxRegExp implements RegExp { JSNativeRegExp regexp = _nativeGlobalVersion; regexp.lastIndex = start.toJS; JSNativeMatch? match = regexp.exec(string.toJS); - if (match.isUndefinedOrNull) return null; - return new _MatchImplementation(this, match!); + return match == null ? null : new _MatchImplementation(this, match); } RegExpMatch? _execAnchored(String string, int start) { JSNativeRegExp regexp = _nativeAnchoredVersion; regexp.lastIndex = start.toJS; JSNativeMatch? match = regexp.exec(string.toJS); - if (match.isUndefinedOrNull) return null; + if (match == null) return null; // If the last capture group participated, the original regexp did not // match at the start position. - if (match!.pop() != null) return null; + if (match.pop() != null) return null; return new _MatchImplementation(this, match); } @@ -201,8 +207,8 @@ class _MatchImplementation implements RegExpMatch { String? namedGroup(String name) { JSObject? groups = _match.groups; - if (groups.isDefinedAndNotNull) { - Object? result = dartifyRaw(groups![name].toExternRef); + if (groups != null) { + Object? result = dartifyRaw(groups[name].toExternRef); if (result != null || hasPropertyRaw(groups.toExternRef, name.toExternRef)) { return result?.toString(); @@ -213,8 +219,8 @@ class _MatchImplementation implements RegExpMatch { Iterable get groupNames { JSObject? groups = _match.groups; - if (groups.isDefinedAndNotNull) { - return JSArrayIterableAdapter(JSObject.keys(groups!)); + if (groups != null) { + return JSArrayIterableAdapter(objectKeys(groups)); } return Iterable.empty(); } diff --git a/sdk/lib/_internal/wasm_js_compatibility/lib/convert_patch.dart b/sdk/lib/_internal/wasm_js_compatibility/lib/convert_patch.dart index 6099d320972..355065ec1ea 100644 --- a/sdk/lib/_internal/wasm_js_compatibility/lib/convert_patch.dart +++ b/sdk/lib/_internal/wasm_js_compatibility/lib/convert_patch.dart @@ -2,13 +2,13 @@ // 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. -import "dart:_internal" show ClassID, patch, POWERS_OF_TEN, unsafeCast; -import "dart:_js_string_convert"; -import "dart:_js_types"; +import 'dart:_internal' show ClassID, patch, POWERS_OF_TEN, unsafeCast; import 'dart:_js_helper' as js; +import 'dart:_js_string_convert'; +import 'dart:_js_types'; import 'dart:_wasm'; - -import "dart:typed_data" show Uint8List, Uint16List; +import 'dart:js_interop'; +import 'dart:typed_data' show Uint8List, Uint16List; @patch dynamic _parseJson( diff --git a/sdk/lib/js_interop/js_interop.dart b/sdk/lib/js_interop/js_interop.dart index 49b518be35f..dca07f3d140 100644 --- a/sdk/lib/js_interop/js_interop.dart +++ b/sdk/lib/js_interop/js_interop.dart @@ -6,10 +6,10 @@ /// interop with JS. The JS type hierarchy is modeled after the actual type /// hierarchy in JS, and not the Dart type hierarchy. /// -/// Note: The JS types that are exposed through this library are currently -/// wrapper types that are erased to their runtime types. The runtime types will -/// differ based on the backend. In general, stick to using conversion functions -/// that are exposed as extension methods e.g. 'toJS'. +/// Note: The JS types defined in this library only provide static guarantees. +/// The runtime types differ based on the backend, so rely on static +/// functionality like the conversion functions e.g. `toJS` and not runtime +/// mechanisms like type checks and casts. /// /// **WARNING**: /// This library is still a work in progress. As such, JS types, allowed syntax, @@ -19,7 +19,7 @@ /// {@category Web} library dart.js_interop; -import 'dart:_js_types' as js_types; +import 'dart:_js_types'; import 'dart:js_interop_unsafe'; import 'dart:typed_data'; @@ -57,91 +57,134 @@ class JS { /// These are meant to separate the Dart and JS type hierarchies statically. /// /// **WARNING**: -/// For now, the runtime semantics between backends may differ and may not be -/// intuitive e.g. casting to [JSString] may give you inconsistent and -/// surprising results depending on the value. It is preferred to always use the -/// conversion functions e.g. `toJS` and `toDart`. The only runtime semantics -/// stability we can guarantee is if a value actually is the JS type you are -/// type-checking with/casting to e.g. `obj as JSString` will continue to work -/// if `obj` actually is a JavaScript string. +/// The runtime semantics between backends differ and may not be intuitive e.g. +/// casting to [JSString] may give you inconsistent and surprising results +/// depending on the value and the backend. It is preferred to always use the +/// conversion functions e.g. `toJS` and `toDart`. You should always use interop +/// to type-check e.g. `typeofEquals` and `instanceOfString` instead of relying +/// on `is` and `as`, as the latter is backend-dependent. /// The overall top type in the JS types hierarchy. -typedef JSAny = js_types.JSAny; +extension type JSAny._(JSAnyRepType _jsAny) implements Object {} -/// The representation type of all JavaScript objects for inline classes, -/// [JSObject] <: [JSAny]. +/// The representation type of all JavaScript objects for extension types. /// /// This is the supertype of all JS objects, but not other JS types, like -/// primitives. This is the only allowed `on` type for inline classes written by -/// users to model JS interop objects. See https://dart.dev/web/js-interop for -/// more details on how to use JS interop. -// TODO(srujzs): This class _must_ be sealed before we can make this library -// public. Either use the CFE mechanisms that exist today, or use the Dart 3 -// sealed classes feature. -// TODO(joshualitt): Do we need to seal any other JS types on JS backends? We -// probably want to seal all JS types on Wasm backends. -// TODO(joshualitt): Add a [JSObject] constructor. -typedef JSObject = js_types.JSObject; +/// primitives. See https://dart.dev/web/js-interop for more details on how to +/// use JS interop. +extension type JSObject._(JSObjectRepType _jsObject) implements JSAny { + /// Constructor to go from an object from previous interop, like the types + /// from `package:js` or `dart:html`, to [JSObject]. + /// + /// This and the public representation field are intended to avoid users + /// having to cast to and from [JSObject]. + JSObject.fromInteropObject(Object interopObject) + : _jsObject = interopObject as JSObjectRepType; -/// The type of all JS functions, [JSFunction] <: [JSObject]. -typedef JSFunction = js_types.JSFunction; + /// Returns a new object literal. + JSObject() : _jsObject = _createObjectLiteral(); +} + +// TODO(srujzs): Move this to `JSObject` once we can patch extension type +// members. +external JSObjectRepType _createObjectLiteral(); + +/// The type of all JS functions. +extension type JSFunction._(JSFunctionRepType _jsFunction) + implements JSObject {} /// The type of all Dart functions adapted to be callable from JS. We only allow -/// a subset of Dart functions to be callable from JS, [JSExportedDartFunction] -/// <: [JSFunction]. +/// a subset of Dart functions to be callable from JS. // TODO(joshualitt): Detail exactly what are the requirements. -typedef JSExportedDartFunction = js_types.JSExportedDartFunction; +extension type JSExportedDartFunction._( + JSExportedDartFunctionRepType _jsExportedDartFunction) + implements JSFunction {} -/// The type of JS promises and promise-like objects, [JSPromise] <: [JSObject]. -typedef JSPromise = js_types.JSPromise; +/// The type of JS promises and promise-like objects. +@JS('Promise') +extension type JSPromise._(JSPromiseRepType _jsPromise) implements JSObject { + external JSPromise(JSFunction executor); +} -/// The type of all JS arrays, [JSArray] <: [JSObject]. -typedef JSArray = js_types.JSArray; +/// The type of all JS arrays. +@JS('Array') +extension type JSArray._(JSArrayRepType _jsArray) implements JSObject { + external JSArray(); + external JSArray.withLength(int length); +} /// The type of the boxed Dart object that can be passed to JS safely. There is /// no interface specified of this boxed object, and you may get a new box each /// time you box the same Dart object. -/// [JSBoxedDartObject] <: [JSObject]. -typedef JSBoxedDartObject = js_types.JSBoxedDartObject; +extension type JSBoxedDartObject._(JSBoxedDartObjectRepType _jsBoxedDartObject) + implements JSObject {} -/// The type of JS array buffers, [JSArrayBuffer] <: [JSObject]. -typedef JSArrayBuffer = js_types.JSArrayBuffer; +/// The type of JS' `ArrayBuffer`. +extension type JSArrayBuffer._(JSArrayBufferRepType _jsArrayBuffer) + implements JSObject {} -/// The type of JS byte data, [JSDataView] <: [JSObject]. -typedef JSDataView = js_types.JSDataView; +/// The type of JS' `DataView`. +extension type JSDataView._(JSDataViewRepType _jsDataView) + implements JSObject {} -/// The abstract supertype of all JS typed arrays, [JSTypedArray] <: [JSObject]. -typedef JSTypedArray = js_types.JSTypedArray; +/// The abstract supertype of all JS typed arrays. +extension type JSTypedArray._(JSTypedArrayRepType _jsTypedArray) + implements JSObject {} -/// The typed arrays themselves, `*Array` <: [JSTypedArray]. -typedef JSInt8Array = js_types.JSInt8Array; -typedef JSUint8Array = js_types.JSUint8Array; -typedef JSUint8ClampedArray = js_types.JSUint8ClampedArray; -typedef JSInt16Array = js_types.JSInt16Array; -typedef JSUint16Array = js_types.JSUint16Array; -typedef JSInt32Array = js_types.JSInt32Array; -typedef JSUint32Array = js_types.JSUint32Array; -typedef JSFloat32Array = js_types.JSFloat32Array; -typedef JSFloat64Array = js_types.JSFloat64Array; +/// The type of JS' `Int8Array`. +extension type JSInt8Array._(JSInt8ArrayRepType _jsInt8Array) + implements JSTypedArray {} + +/// The type of JS' `Uint8Array`. +extension type JSUint8Array._(JSUint8ArrayRepType _jsUint8Array) + implements JSTypedArray {} + +/// The type of JS' `Uint8ClampedArray`. +extension type JSUint8ClampedArray._( + JSUint8ClampedArrayRepType _jsUint8ClampedArray) implements JSTypedArray {} + +/// The type of JS' `Int16Array`. +extension type JSInt16Array._(JSInt16ArrayRepType _jsInt16Array) + implements JSTypedArray {} + +/// The type of JS' `Uint16Array`. +extension type JSUint16Array._(JSUint16ArrayRepType _jsUint16Array) + implements JSTypedArray {} + +/// The type of JS' `Int32Array`. +extension type JSInt32Array._(JSInt32ArrayRepType _jsInt32Array) + implements JSTypedArray {} + +/// The type of JS' `Uint32Array`. +extension type JSUint32Array._(JSUint32ArrayRepType _jsUint32Array) + implements JSTypedArray {} + +/// The type of JS' `Float32Array`. +extension type JSFloat32Array._(JSFloat32ArrayRepType _jsFloat32Array) + implements JSTypedArray {} + +/// The type of JS' `Float64Array`. +extension type JSFloat64Array._(JSFloat64ArrayRepType _jsFloat64Array) + implements JSTypedArray {} // The various JS primitive types. Crucially, unlike the Dart type hierarchy, // none of these are subtypes of [JSObject], but rather they are logically // subtypes of [JSAny]. -/// The type of JS numbers, [JSNumber] <: [JSAny]. -typedef JSNumber = js_types.JSNumber; +/// The type of JS numbers. +extension type JSNumber._(JSNumberRepType _jsNumber) implements JSAny {} -/// The type of JS booleans, [JSBoolean] <: [JSAny]. -typedef JSBoolean = js_types.JSBoolean; +/// The type of JS booleans. +extension type JSBoolean._(JSBooleanRepType _jsBoolean) implements JSAny {} -/// The type of JS strings, [JSString] <: [JSAny]. -typedef JSString = js_types.JSString; +/// The type of JS strings. +extension type JSString._(JSStringRepType _jsString) implements JSAny {} -/// The type of JS Symbols, [JSSymbol] <: [JSAny]. -typedef JSSymbol = js_types.JSSymbol; +/// The type of JS `Symbol`s. +extension type JSSymbol._(JSSymbolRepType _jsSymbol) implements JSAny {} -/// The type of JS BigInts, [JSBigInt] <: [JSAny]. -typedef JSBigInt = js_types.JSBigInt; +/// The type of JS `BigInt`s. +extension type JSBigInt._(JSBigIntRepType _jsBigInt) implements JSAny {} /// A getter to retrieve the global context that is used in static interop /// lowering. @@ -207,11 +250,13 @@ extension JSObjectUtilExtension on JSObject { /// The type of `JSUndefined` when returned from functions. Unlike pure JS, /// no actual object will be returned. -typedef JSVoid = js_types.JSVoid; +// TODO(srujzs): Should we just remove this? There are no performance costs from +// using `void`, and we'll likely provide a different way to box `undefined`. +typedef JSVoid = JSVoidRepType; // 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(joshualitt): We might want to investigate using inline classes instead +// TODO(joshualitt): We might want to investigate using extension types instead // of extension methods for these methods. /// [JSExportedDartFunction] <-> [Function] diff --git a/tests/lib/js/static_interop_test/inline_class/external_extension_member_test.dart b/tests/lib/js/static_interop_test/extension_type/external_extension_member_test.dart similarity index 100% rename from tests/lib/js/static_interop_test/inline_class/external_extension_member_test.dart rename to tests/lib/js/static_interop_test/extension_type/external_extension_member_test.dart diff --git a/tests/lib/js/static_interop_test/inline_class/external_member_test.dart b/tests/lib/js/static_interop_test/extension_type/external_member_test.dart similarity index 100% rename from tests/lib/js/static_interop_test/inline_class/external_member_test.dart rename to tests/lib/js/static_interop_test/extension_type/external_member_test.dart diff --git a/tests/lib/js/static_interop_test/inline_class/external_static_member_test.dart b/tests/lib/js/static_interop_test/extension_type/external_static_member_test.dart similarity index 100% rename from tests/lib/js/static_interop_test/inline_class/external_static_member_test.dart rename to tests/lib/js/static_interop_test/extension_type/external_static_member_test.dart diff --git a/tests/lib/js/static_interop_test/inline_class/external_static_member_with_namespaces_test.dart b/tests/lib/js/static_interop_test/extension_type/external_static_member_with_namespaces_test.dart similarity index 100% rename from tests/lib/js/static_interop_test/inline_class/external_static_member_with_namespaces_test.dart rename to tests/lib/js/static_interop_test/extension_type/external_static_member_with_namespaces_test.dart diff --git a/tests/lib/js/static_interop_test/inline_class/incorrect_js_annotation_static_test.dart b/tests/lib/js/static_interop_test/extension_type/incorrect_js_annotation_static_test.dart similarity index 100% rename from tests/lib/js/static_interop_test/inline_class/incorrect_js_annotation_static_test.dart rename to tests/lib/js/static_interop_test/extension_type/incorrect_js_annotation_static_test.dart diff --git a/tests/lib/js/static_interop_test/inline_class/no_library_declaration_static_test.dart b/tests/lib/js/static_interop_test/extension_type/no_library_declaration_static_test.dart similarity index 100% rename from tests/lib/js/static_interop_test/inline_class/no_library_declaration_static_test.dart rename to tests/lib/js/static_interop_test/extension_type/no_library_declaration_static_test.dart diff --git a/tests/lib/js/static_interop_test/inline_class/non_interop_inline_class_static_test.dart b/tests/lib/js/static_interop_test/extension_type/non_interop_extension_type_static_test.dart similarity index 99% rename from tests/lib/js/static_interop_test/inline_class/non_interop_inline_class_static_test.dart rename to tests/lib/js/static_interop_test/extension_type/non_interop_extension_type_static_test.dart index b9bb2ab1c9e..28b365387de 100644 --- a/tests/lib/js/static_interop_test/inline_class/non_interop_inline_class_static_test.dart +++ b/tests/lib/js/static_interop_test/extension_type/non_interop_extension_type_static_test.dart @@ -79,6 +79,7 @@ extension type EExtensionType(EJSObject _) {} @JS() extension type EExtensionType2(EExtensionType _) {} + @JS() extension type ENonInterop._(EObject _) { // ^ diff --git a/tests/lib/js/static_interop_test/inline_class/object_literal_constructor_test.dart b/tests/lib/js/static_interop_test/extension_type/object_literal_constructor_test.dart similarity index 100% rename from tests/lib/js/static_interop_test/inline_class/object_literal_constructor_test.dart rename to tests/lib/js/static_interop_test/extension_type/object_literal_constructor_test.dart diff --git a/tests/lib/js/static_interop_test/inline_class/parameters_static_test.dart b/tests/lib/js/static_interop_test/extension_type/parameters_static_test.dart similarity index 100% rename from tests/lib/js/static_interop_test/inline_class/parameters_static_test.dart rename to tests/lib/js/static_interop_test/extension_type/parameters_static_test.dart diff --git a/tests/lib/js/static_interop_test/subtype_js_types_static_test.dart b/tests/lib/js/static_interop_test/subtype_js_types_static_test.dart deleted file mode 100644 index 408b6881de4..00000000000 --- a/tests/lib/js/static_interop_test/subtype_js_types_static_test.dart +++ /dev/null @@ -1,279 +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. - -@JS() -library subtype_js_types_static_test; - -import 'dart:js_interop'; - -@JS() -@staticInterop -class ExtendsJSAny extends JSAny {} -// ^ -// [web] The superclass, 'JSAny', has no unnamed constructor that takes no arguments. -// ^^^^^ -// [analyzer] COMPILE_TIME_ERROR.NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS - -@JS() -@staticInterop -class ImplementsJSAny implements JSAny {} - -@JS() -@staticInterop -class ExtendsJSObject extends JSObject {} -// ^ -// [web] The superclass, 'JSObject', has no unnamed constructor that takes no arguments. -// ^^^^^^^^ -// [analyzer] COMPILE_TIME_ERROR.NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS - -@JS() -@staticInterop -class ImplementsJSObject implements JSObject {} - -@JS() -@staticInterop -class ExtendsJSFunction extends JSFunction {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSFunction' cannot have 'JSFunction' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSFunction implements JSFunction {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSFunction' cannot have 'JSFunction' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSExportedDartFunction extends JSExportedDartFunction {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSExportedDartFunction' cannot have 'JSExportedDartFunction' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSExportedDartFunction implements JSExportedDartFunction {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSExportedDartFunction' cannot have 'JSExportedDartFunction' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSArray extends JSArray { -// ^ -// [web] `@staticInterop` class 'ExtendsJSArray' cannot have 'JSArray' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - - // Silence error about extending class with only factories. - external factory ExtendsJSArray(); -} - -@JS() -@staticInterop -class ImplementsJSArray implements JSArray {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSArray' cannot have 'JSArray' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSBoxedDartObject extends JSBoxedDartObject {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSBoxedDartObject' cannot have 'JSBoxedDartObject' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSBoxedDartObject implements JSBoxedDartObject {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSBoxedDartObject' cannot have 'JSBoxedDartObject' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSArrayBuffer extends JSArrayBuffer {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSArrayBuffer' cannot have 'JSArrayBuffer' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSArrayBuffer implements JSArrayBuffer {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSArrayBuffer' cannot have 'JSArrayBuffer' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSDataView extends JSDataView {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSDataView' cannot have 'JSDataView' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSDataView implements JSDataView {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSDataView' cannot have 'JSDataView' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSTypedArray extends JSTypedArray {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSTypedArray' cannot have 'JSTypedArray' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSTypedArray implements JSTypedArray {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSTypedArray' cannot have 'JSTypedArray' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSInt8Array extends JSInt8Array {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSInt8Array' cannot have 'JSInt8Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSInt8Array implements JSInt8Array {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSInt8Array' cannot have 'JSInt8Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSUint8Array extends JSUint8Array {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSUint8Array' cannot have 'JSUint8Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSUint8Array implements JSUint8Array {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSUint8Array' cannot have 'JSUint8Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSUint8ClampedArray extends JSUint8ClampedArray {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSUint8ClampedArray' cannot have 'JSUint8ClampedArray' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSUint8ClampedArray implements JSUint8ClampedArray {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSUint8ClampedArray' cannot have 'JSUint8ClampedArray' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSInt16Array extends JSInt16Array {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSInt16Array' cannot have 'JSInt16Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSInt16Array implements JSInt16Array {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSInt16Array' cannot have 'JSInt16Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSUint16Array extends JSUint16Array {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSUint16Array' cannot have 'JSUint16Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSUint16Array implements JSUint16Array {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSUint16Array' cannot have 'JSUint16Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSInt32Array extends JSInt32Array {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSInt32Array' cannot have 'JSInt32Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSInt32Array implements JSInt32Array {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSInt32Array' cannot have 'JSInt32Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSUint32Array extends JSUint32Array {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSUint32Array' cannot have 'JSUint32Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSUint32Array implements JSUint32Array {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSUint32Array' cannot have 'JSUint32Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSFloat32Array extends JSFloat32Array {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSFloat32Array' cannot have 'JSFloat32Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSFloat32Array implements JSFloat32Array {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSFloat32Array' cannot have 'JSFloat32Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSFloat64Array extends JSFloat64Array {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSFloat64Array' cannot have 'JSFloat64Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSFloat64Array implements JSFloat64Array {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSFloat64Array' cannot have 'JSFloat64Array' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSNumber extends JSNumber {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSNumber' cannot have 'JSNumber' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSNumber implements JSNumber {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSNumber' cannot have 'JSNumber' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSBoolean extends JSBoolean {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSBoolean' cannot have 'JSBoolean' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSBoolean implements JSBoolean {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSBoolean' cannot have 'JSBoolean' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSString extends JSString {} -// ^ -// [web] `@staticInterop` class 'ExtendsJSString' cannot have 'JSString' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ImplementsJSString implements JSString {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSString' cannot have 'JSString' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. - -@JS() -@staticInterop -class ExtendsJSPromise extends JSPromise {} -// ^ -// [web] The superclass, 'JSPromise', has no unnamed constructor that takes no arguments. -// [web] `@staticInterop` class 'ExtendsJSPromise' cannot have 'JSPromise' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. -// ^^^^^^^^^ -// [analyzer] COMPILE_TIME_ERROR.NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS - -@JS() -@staticInterop -class ImplementsJSPromise implements JSPromise {} -// ^ -// [web] `@staticInterop` class 'ImplementsJSPromise' cannot have 'JSPromise' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes. diff --git a/tests/lib/lib.status b/tests/lib/lib.status index 37a1d1f7eb1..69d5a570227 100644 --- a/tests/lib/lib.status +++ b/tests/lib/lib.status @@ -14,8 +14,8 @@ fix_data_tests/*: SkipByDesign html/*: SkipByDesign # dart:html not supported on dart2wasm isolate/*: SkipByDesign js/(?!export|static_interop_test)*: SkipByDesign +js/static_interop_test/extension_type/non_interop_extension_type_static_test: SkipByDesign # Some external checks are not run on dart2wasm. js/static_interop_test/external_static_member_lowerings_trusttypes_test: SkipByDesign # Tests @trustTypes, which is unsupported on dart2wasm. -js/static_interop_test/inline_class/non_interop_inline_class_static_test: SkipByDesign # Some external checks are not run on dart2wasm. js/static_interop_test/static_external_extension_members_static_test: SkipByDesign # dart:html not supported on dart2wasm. js/static_interop_test/top_level_member_annotation_static_test: SkipByDesign # Some external checks are not run on dart2wasm. mirrors/*: SkipByDesign @@ -72,14 +72,14 @@ js/js_util/properties_test: SkipByDesign # Issue 42085. CSP policy disallows inj js/method_call_on_object_test: SkipByDesign # Issue 42085. js/mock_test/*: SkipByDesign # Issue 42085. js/parameters_test: SkipByDesign # Issue 42085. +js/static_interop_test/extension_type/external_extension_member_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code +js/static_interop_test/extension_type/external_member_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code +js/static_interop_test/extension_type/external_static_member_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code +js/static_interop_test/extension_type/external_static_member_with_namespaces_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code js/static_interop_test/external_extension_members_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code js/static_interop_test/external_static_member_lowerings_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code js/static_interop_test/external_static_member_lowerings_trusttypes_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code js/static_interop_test/external_static_member_lowerings_with_namespaces_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code -js/static_interop_test/inline_class/external_extension_member_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code -js/static_interop_test/inline_class/external_member_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code -js/static_interop_test/inline_class/external_static_member_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code -js/static_interop_test/inline_class/external_static_member_with_namespaces_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code js/static_interop_test/js_array_proxy_or_ref_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code js/static_interop_test/js_array_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code js/static_interop_test/js_function_conversions_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code