diff --git a/CHANGELOG.md b/CHANGELOG.md index 41f50dee..508c7662 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.1-dev + +- Updated types to account for union types. + ## 0.3.0 - Updated source IDL to `v3.39.1`. diff --git a/lib/src/dom/credential_management.dart b/lib/src/dom/credential_management.dart index 555835b1..74a971c6 100644 --- a/lib/src/dom/credential_management.dart +++ b/lib/src/dom/credential_management.dart @@ -9,7 +9,7 @@ import 'fedcm.dart'; import 'web_otp.dart'; import 'webauthn.dart'; -typedef PasswordCredentialInit = JSAny?; +typedef PasswordCredentialInit = JSObject; typedef CredentialMediationRequirement = String; @JS('Credential') @@ -113,7 +113,7 @@ extension CredentialCreationOptionsExtension on CredentialCreationOptions { @JS('PasswordCredential') @staticInterop class PasswordCredential implements Credential, CredentialUserData { - external factory PasswordCredential(JSAny? dataOrForm); + external factory PasswordCredential(JSObject dataOrForm); } extension PasswordCredentialExtension on PasswordCredential { diff --git a/lib/src/dom/css_animation_worklet.dart b/lib/src/dom/css_animation_worklet.dart index e1158cc9..ec04e2a0 100644 --- a/lib/src/dom/css_animation_worklet.dart +++ b/lib/src/dom/css_animation_worklet.dart @@ -36,7 +36,7 @@ extension WorkletAnimationEffectExtension on WorkletAnimationEffect { class WorkletAnimation implements Animation { external factory WorkletAnimation( String animatorName, [ - JSAny? effects, + JSObject? effects, AnimationTimeline? timeline, JSAny? options, ]); diff --git a/lib/src/dom/css_font_loading.dart b/lib/src/dom/css_font_loading.dart index 5ce1dc36..fd206a71 100644 --- a/lib/src/dom/css_font_loading.dart +++ b/lib/src/dom/css_font_loading.dart @@ -7,7 +7,7 @@ import 'dart:js_interop'; import 'dom.dart'; import 'html.dart'; -typedef BinaryData = JSAny?; +typedef BinaryData = JSObject; typedef FontFaceLoadStatus = String; typedef FontFaceSetLoadStatus = String; diff --git a/lib/src/dom/css_pseudo.dart b/lib/src/dom/css_pseudo.dart index 78436df4..36f0f8f7 100644 --- a/lib/src/dom/css_pseudo.dart +++ b/lib/src/dom/css_pseudo.dart @@ -15,5 +15,5 @@ extension CSSPseudoElementExtension on CSSPseudoElement { external CSSPseudoElement? pseudo(String type); external String get type; external Element get element; - external JSAny? get parent; + external JSObject get parent; } diff --git a/lib/src/dom/css_typed_om.dart b/lib/src/dom/css_typed_om.dart index e4ad5fa1..fa55b416 100644 --- a/lib/src/dom/css_typed_om.dart +++ b/lib/src/dom/css_typed_om.dart @@ -419,7 +419,7 @@ class CSSImageValue implements CSSStyleValue {} @JS('CSSColorValue') @staticInterop class CSSColorValue implements CSSStyleValue { - external static JSAny? parse(String cssText); + external static JSObject parse(String cssText); } @JS('CSSRGB') diff --git a/lib/src/dom/cssom.dart b/lib/src/dom/cssom.dart index 3c0b7cd5..8e63db2d 100644 --- a/lib/src/dom/cssom.dart +++ b/lib/src/dom/cssom.dart @@ -30,7 +30,7 @@ class StyleSheet implements JSObject {} extension StyleSheetExtension on StyleSheet { external String get type; external String? get href; - external JSAny? get ownerNode; + external JSObject? get ownerNode; external CSSStyleSheet? get parentStyleSheet; external String? get title; external MediaList get media; diff --git a/lib/src/dom/cssom_view.dart b/lib/src/dom/cssom_view.dart index 98a79d43..ad6dc375 100644 --- a/lib/src/dom/cssom_view.dart +++ b/lib/src/dom/cssom_view.dart @@ -9,7 +9,7 @@ import 'geometry.dart'; import 'html.dart'; import 'screen_orientation.dart'; -typedef GeometryNode = JSAny?; +typedef GeometryNode = JSObject; typedef ScrollBehavior = String; typedef ScrollLogicalPosition = String; typedef CSSBoxType = String; diff --git a/lib/src/dom/dom.dart b/lib/src/dom/dom.dart index aa0db2a9..ebe2abf3 100644 --- a/lib/src/dom/dom.dart +++ b/lib/src/dom/dom.dart @@ -512,7 +512,7 @@ extension DocumentExtension on Document { ); external JSPromise exitFullscreen(); external NodeList getElementsByName(String elementName); - external JSAny? open([ + external JSObject? open([ String unused1OrUrl, String nameOrUnused2, String features, diff --git a/lib/src/dom/html.dart b/lib/src/dom/html.dart index 9cfd6a7b..507e0b97 100644 --- a/lib/src/dom/html.dart +++ b/lib/src/dom/html.dart @@ -82,18 +82,18 @@ import 'webxr.dart'; import 'window_controls_overlay.dart'; import 'xhr.dart'; -typedef HTMLOrSVGScriptElement = JSAny?; -typedef MediaProvider = JSAny?; -typedef RenderingContext = JSAny?; -typedef HTMLOrSVGImageElement = JSAny?; -typedef CanvasImageSource = JSAny?; -typedef OffscreenRenderingContext = JSAny?; +typedef HTMLOrSVGScriptElement = JSObject; +typedef MediaProvider = JSObject; +typedef RenderingContext = JSObject; +typedef HTMLOrSVGImageElement = JSObject; +typedef CanvasImageSource = JSObject; +typedef OffscreenRenderingContext = JSObject; typedef EventHandler = EventHandlerNonNull?; typedef OnErrorEventHandler = OnErrorEventHandlerNonNull?; typedef OnBeforeUnloadEventHandler = OnBeforeUnloadEventHandlerNonNull?; typedef TimerHandler = JSAny?; -typedef ImageBitmapSource = JSAny?; -typedef MessageEventSource = JSAny?; +typedef ImageBitmapSource = JSObject; +typedef MessageEventSource = JSObject; typedef BlobCallback = JSFunction; typedef CustomElementConstructor = JSFunction; typedef FunctionStringCallback = JSFunction; @@ -138,8 +138,8 @@ typedef WorkerType = String; class HTMLAllCollection implements JSObject {} extension HTMLAllCollectionExtension on HTMLAllCollection { - external JSAny? namedItem(String name); - external JSAny? item([String nameOrIndex]); + external JSObject? namedItem(String name); + external JSObject? item([String nameOrIndex]); external int get length; } @@ -148,7 +148,7 @@ extension HTMLAllCollectionExtension on HTMLAllCollection { class HTMLFormControlsCollection implements HTMLCollection {} extension HTMLFormControlsCollectionExtension on HTMLFormControlsCollection { - external JSAny? namedItem(String name); + external JSObject? namedItem(String name); } @JS('RadioNodeList') @@ -166,7 +166,7 @@ class HTMLOptionsCollection implements HTMLCollection {} extension HTMLOptionsCollectionExtension on HTMLOptionsCollection { external JSVoid add( - JSAny? element, [ + JSObject element, [ JSAny? before, ]); external JSVoid remove(int index); @@ -1182,19 +1182,19 @@ class TrackEvent implements Event { } extension TrackEventExtension on TrackEvent { - external JSAny? get track; + external JSObject? get track; } @JS() @staticInterop @anonymous class TrackEventInit implements EventInit { - external factory TrackEventInit({JSAny? track}); + external factory TrackEventInit({JSObject? track}); } extension TrackEventInitExtension on TrackEventInit { - external set track(JSAny? value); - external JSAny? get track; + external set track(JSObject? value); + external JSObject? get track; } @JS('HTMLMapElement') @@ -1606,7 +1606,7 @@ extension HTMLSelectElementExtension on HTMLSelectElement { external HTMLOptionElement? item(int index); external HTMLOptionElement? namedItem(String name); external JSVoid add( - JSAny? element, [ + JSObject element, [ JSAny? before, ]); external JSVoid remove([int index]); @@ -2002,7 +2002,7 @@ class HTMLSlotElement implements HTMLElement { extension HTMLSlotElementExtension on HTMLSlotElement { external JSArray assignedNodes([AssignedNodesOptions options]); external JSArray assignedElements([AssignedNodesOptions options]); - external JSVoid assign(JSAny? nodes); + external JSVoid assign(JSObject nodes); external set name(String value); external String get name; } @@ -2281,7 +2281,7 @@ class CanvasUserInterface implements JSObject {} extension CanvasUserInterfaceExtension on CanvasUserInterface { external JSVoid drawFocusIfNeeded( - JSAny? elementOrPath, [ + JSObject elementOrPath, [ Element element, ]); external JSVoid scrollPathIntoView([Path2D path]); @@ -2554,7 +2554,7 @@ class ImageBitmapRenderingContext implements JSObject {} extension ImageBitmapRenderingContextExtension on ImageBitmapRenderingContext { external JSVoid transferFromImageBitmap(ImageBitmap? bitmap); - external JSAny? get canvas; + external JSObject get canvas; } @JS() @@ -4228,7 +4228,7 @@ class MessagePort implements EventTarget {} extension MessagePortExtension on MessagePort { external JSVoid postMessage( JSAny? message, [ - JSAny? optionsOrTransfer, + JSObject optionsOrTransfer, ]); external JSVoid start(); external JSVoid close(); @@ -4298,7 +4298,7 @@ class DedicatedWorkerGlobalScope extension DedicatedWorkerGlobalScopeExtension on DedicatedWorkerGlobalScope { external JSVoid postMessage( JSAny? message, [ - JSAny? optionsOrTransfer, + JSObject optionsOrTransfer, ]); external JSVoid close(); external String get name; @@ -4343,7 +4343,7 @@ extension WorkerExtension on Worker { external JSVoid terminate(); external JSVoid postMessage( JSAny? message, [ - JSAny? optionsOrTransfer, + JSObject optionsOrTransfer, ]); external set onmessage(EventHandler value); external EventHandler get onmessage; diff --git a/lib/src/dom/image_capture.dart b/lib/src/dom/image_capture.dart index 6103ef28..166ecf0d 100644 --- a/lib/src/dom/image_capture.dart +++ b/lib/src/dom/image_capture.dart @@ -6,7 +6,7 @@ import 'dart:js_interop'; import 'mediacapture_streams.dart'; -typedef ConstrainPoint2D = JSAny?; +typedef ConstrainPoint2D = JSObject; typedef RedEyeReduction = String; typedef FillLightMode = String; typedef MeteringMode = String; diff --git a/lib/src/dom/indexeddb.dart b/lib/src/dom/indexeddb.dart index fbf7a0f9..64feffcc 100644 --- a/lib/src/dom/indexeddb.dart +++ b/lib/src/dom/indexeddb.dart @@ -20,7 +20,7 @@ class IDBRequest implements EventTarget {} extension IDBRequestExtension on IDBRequest { external JSAny? get result; external DOMException? get error; - external JSAny? get source; + external JSObject? get source; external IDBTransaction? get transaction; external IDBRequestReadyState get readyState; external set onsuccess(EventHandler value); @@ -303,7 +303,7 @@ extension IDBCursorExtension on IDBCursor { ); external IDBRequest update(JSAny? value); external IDBRequest delete(); - external JSAny? get source; + external JSObject get source; external IDBCursorDirection get direction; external JSAny? get key; external JSAny? get primaryKey; diff --git a/lib/src/dom/intersection_observer.dart b/lib/src/dom/intersection_observer.dart index a039d4cd..ee0a531a 100644 --- a/lib/src/dom/intersection_observer.dart +++ b/lib/src/dom/intersection_observer.dart @@ -24,7 +24,7 @@ extension IntersectionObserverExtension on IntersectionObserver { external JSVoid unobserve(Element target); external JSVoid disconnect(); external JSArray takeRecords(); - external JSAny? get root; + external JSObject? get root; external String get rootMargin; external String get scrollMargin; external JSArray get thresholds; @@ -85,7 +85,7 @@ extension IntersectionObserverEntryInitExtension @anonymous class IntersectionObserverInit implements JSObject { external factory IntersectionObserverInit({ - JSAny? root, + JSObject? root, String rootMargin, String scrollMargin, JSAny? threshold, @@ -93,8 +93,8 @@ class IntersectionObserverInit implements JSObject { } extension IntersectionObserverInitExtension on IntersectionObserverInit { - external set root(JSAny? value); - external JSAny? get root; + external set root(JSObject? value); + external JSObject? get root; external set rootMargin(String value); external String get rootMargin; external set scrollMargin(String value); diff --git a/lib/src/dom/mediacapture_streams.dart b/lib/src/dom/mediacapture_streams.dart index aaae668b..6145d940 100644 --- a/lib/src/dom/mediacapture_streams.dart +++ b/lib/src/dom/mediacapture_streams.dart @@ -29,7 +29,7 @@ typedef MediaDeviceKind = String; @JS('MediaStream') @staticInterop class MediaStream implements EventTarget { - external factory MediaStream([JSAny? streamOrTracks]); + external factory MediaStream([JSObject streamOrTracks]); } extension MediaStreamExtension on MediaStream { diff --git a/lib/src/dom/orientation_sensor.dart b/lib/src/dom/orientation_sensor.dart index c244546e..0a93b56b 100644 --- a/lib/src/dom/orientation_sensor.dart +++ b/lib/src/dom/orientation_sensor.dart @@ -6,7 +6,7 @@ import 'dart:js_interop'; import 'generic_sensor.dart'; -typedef RotationMatrixType = JSAny?; +typedef RotationMatrixType = JSObject; typedef OrientationSensorLocalCoordinateSystem = String; @JS('OrientationSensor') diff --git a/lib/src/dom/sanitizer_api.dart b/lib/src/dom/sanitizer_api.dart index 9b876905..5459b708 100644 --- a/lib/src/dom/sanitizer_api.dart +++ b/lib/src/dom/sanitizer_api.dart @@ -17,7 +17,7 @@ class Sanitizer implements JSObject { } extension SanitizerExtension on Sanitizer { - external DocumentFragment sanitize(JSAny? input); + external DocumentFragment sanitize(JSObject input); external Element? sanitizeFor( String element, String input, diff --git a/lib/src/dom/service_workers.dart b/lib/src/dom/service_workers.dart index 3241bbd8..649458b0 100644 --- a/lib/src/dom/service_workers.dart +++ b/lib/src/dom/service_workers.dart @@ -29,7 +29,7 @@ class ServiceWorker implements EventTarget, AbstractWorker {} extension ServiceWorkerExtension on ServiceWorker { external JSVoid postMessage( JSAny? message, [ - JSAny? optionsOrTransfer, + JSObject optionsOrTransfer, ]); external String get scriptURL; external ServiceWorkerState get state; @@ -193,7 +193,7 @@ class Client implements JSObject {} extension ClientExtension on Client { external JSVoid postMessage( JSAny? message, [ - JSAny? optionsOrTransfer, + JSObject optionsOrTransfer, ]); external ClientLifecycleState get lifecycleState; external String get url; @@ -323,7 +323,7 @@ extension ExtendableMessageEventExtension on ExtendableMessageEvent { external JSAny? get data; external String get origin; external String get lastEventId; - external JSAny? get source; + external JSObject? get source; external JSArray get ports; } @@ -335,7 +335,7 @@ class ExtendableMessageEventInit implements ExtendableEventInit { JSAny? data, String origin, String lastEventId, - JSAny? source, + JSObject? source, JSArray ports, }); } @@ -347,8 +347,8 @@ extension ExtendableMessageEventInitExtension on ExtendableMessageEventInit { external String get origin; external set lastEventId(String value); external String get lastEventId; - external set source(JSAny? value); - external JSAny? get source; + external set source(JSObject? value); + external JSObject? get source; external set ports(JSArray value); external JSArray get ports; } diff --git a/lib/src/dom/streams.dart b/lib/src/dom/streams.dart index d354df5f..43c99e52 100644 --- a/lib/src/dom/streams.dart +++ b/lib/src/dom/streams.dart @@ -7,8 +7,8 @@ import 'dart:js_interop'; import 'dom.dart'; import 'webidl.dart'; -typedef ReadableStreamReader = JSAny?; -typedef ReadableStreamController = JSAny?; +typedef ReadableStreamReader = JSObject; +typedef ReadableStreamController = JSObject; typedef UnderlyingSourceStartCallback = JSFunction; typedef UnderlyingSourcePullCallback = JSFunction; typedef UnderlyingSourceCancelCallback = JSFunction; diff --git a/lib/src/dom/svg.dart b/lib/src/dom/svg.dart index c375bfcc..b6faef77 100644 --- a/lib/src/dom/svg.dart +++ b/lib/src/dom/svg.dart @@ -437,7 +437,7 @@ extension SVGElementInstanceExtension on SVGElementInstance { class ShadowAnimation implements Animation { external factory ShadowAnimation( Animation source, - JSAny? newTarget, + JSObject newTarget, ); } diff --git a/lib/src/dom/trusted_types.dart b/lib/src/dom/trusted_types.dart index e4b88bfe..09ec71a3 100644 --- a/lib/src/dom/trusted_types.dart +++ b/lib/src/dom/trusted_types.dart @@ -7,7 +7,7 @@ import 'dart:js_interop'; typedef HTMLString = String; typedef ScriptString = String; typedef ScriptURLString = String; -typedef TrustedType = JSAny?; +typedef TrustedType = JSObject; typedef CreateHTMLCallback = JSFunction; typedef CreateScriptCallback = JSFunction; typedef CreateScriptURLCallback = JSFunction; diff --git a/lib/src/dom/url.dart b/lib/src/dom/url.dart index a6be4e9f..21b4e108 100644 --- a/lib/src/dom/url.dart +++ b/lib/src/dom/url.dart @@ -12,7 +12,7 @@ class URL implements JSObject { String base, ]); - external static String createObjectURL(JSAny? obj); + external static String createObjectURL(JSObject obj); external static JSVoid revokeObjectURL(String url); external static bool canParse( String url, [ diff --git a/lib/src/dom/wasm_js_api.dart b/lib/src/dom/wasm_js_api.dart index be69af02..69b57c3a 100644 --- a/lib/src/dom/wasm_js_api.dart +++ b/lib/src/dom/wasm_js_api.dart @@ -39,7 +39,7 @@ extension $WebAssemblyExtension on $WebAssembly { external bool validate(BufferSource bytes); external JSPromise compile(BufferSource bytes); external JSPromise instantiate( - JSAny? bytesOrModuleObject, [ + JSObject bytesOrModuleObject, [ JSObject importObject, ]); external JSPromise compileStreaming(JSPromise source); diff --git a/lib/src/dom/web_animations.dart b/lib/src/dom/web_animations.dart index 7afa0c04..0a0398c1 100644 --- a/lib/src/dom/web_animations.dart +++ b/lib/src/dom/web_animations.dart @@ -214,7 +214,7 @@ extension ComputedEffectTimingExtension on ComputedEffectTiming { @staticInterop class KeyframeEffect implements AnimationEffect { external factory KeyframeEffect( - JSAny? sourceOrTarget, [ + JSObject? sourceOrTarget, [ JSObject? keyframes, JSAny? options, ]); diff --git a/lib/src/dom/web_locks.dart b/lib/src/dom/web_locks.dart index e2680f77..f3eb6606 100644 --- a/lib/src/dom/web_locks.dart +++ b/lib/src/dom/web_locks.dart @@ -24,7 +24,7 @@ class LockManager implements JSObject {} extension LockManagerExtension on LockManager { external JSPromise request( String name, - JSAny? callbackOrOptions, [ + JSObject callbackOrOptions, [ LockGrantedCallback callback, ]); external JSPromise query(); diff --git a/lib/src/dom/webaudio.dart b/lib/src/dom/webaudio.dart index ed459a75..b292d48c 100644 --- a/lib/src/dom/webaudio.dart +++ b/lib/src/dom/webaudio.dart @@ -349,7 +349,7 @@ class AudioNode implements EventTarget {} extension AudioNodeExtension on AudioNode { external JSAny? connect( - JSAny? destinationNodeOrDestinationParam, [ + JSObject destinationNodeOrDestinationParam, [ int output, int input, ]); diff --git a/lib/src/dom/webcodecs.dart b/lib/src/dom/webcodecs.dart index f8c38a3c..a4c927eb 100644 --- a/lib/src/dom/webcodecs.dart +++ b/lib/src/dom/webcodecs.dart @@ -17,7 +17,7 @@ import 'webcodecs_opus_codec_registration.dart'; import 'webcodecs_vp9_codec_registration.dart'; import 'webidl.dart'; -typedef ImageBufferSource = JSAny?; +typedef ImageBufferSource = JSObject; typedef AudioDataOutputCallback = JSFunction; typedef VideoFrameOutputCallback = JSFunction; typedef EncodedAudioChunkOutputCallback = JSFunction; @@ -633,8 +633,8 @@ extension AudioDataCopyToOptionsExtension on AudioDataCopyToOptions { @staticInterop class VideoFrame implements JSObject { external factory VideoFrame( - JSAny? dataOrImage, [ - JSAny? init, + JSObject dataOrImage, [ + JSObject init, ]); } diff --git a/lib/src/dom/webcryptoapi.dart b/lib/src/dom/webcryptoapi.dart index 32707288..ab5f544c 100644 --- a/lib/src/dom/webcryptoapi.dart +++ b/lib/src/dom/webcryptoapi.dart @@ -108,7 +108,7 @@ extension SubtleCryptoExtension on SubtleCrypto { ); external JSPromise importKey( KeyFormat format, - JSAny? keyData, + JSObject keyData, AlgorithmIdentifier algorithm, bool extractable, JSArray keyUsages, diff --git a/lib/src/dom/webgl1.dart b/lib/src/dom/webgl1.dart index d67618d2..7cd64607 100644 --- a/lib/src/dom/webgl1.dart +++ b/lib/src/dom/webgl1.dart @@ -22,9 +22,9 @@ typedef GLushort = int; typedef GLuint = int; typedef GLfloat = num; typedef GLclampf = num; -typedef TexImageSource = JSAny?; -typedef Float32List = JSAny?; -typedef Int32List = JSAny?; +typedef TexImageSource = JSObject; +typedef Float32List = JSObject; +typedef Int32List = JSObject; typedef WebGLPowerPreference = String; @JS() @@ -805,7 +805,7 @@ extension WebGLRenderingContextBaseExtension on WebGLRenderingContextBase { GLsizei height, ); external JSPromise makeXRCompatible(); - external JSAny? get canvas; + external JSObject get canvas; external GLsizei get drawingBufferWidth; external GLsizei get drawingBufferHeight; external set drawingBufferColorSpace(PredefinedColorSpace value); diff --git a/lib/src/dom/webgl2.dart b/lib/src/dom/webgl2.dart index c31ee2e0..e5cb32a2 100644 --- a/lib/src/dom/webgl2.dart +++ b/lib/src/dom/webgl2.dart @@ -9,7 +9,7 @@ import 'webidl.dart'; typedef GLint64 = int; typedef GLuint64 = int; -typedef Uint32List = JSAny?; +typedef Uint32List = JSObject; @JS('WebGLQuery') @staticInterop @@ -750,7 +750,7 @@ extension WebGL2RenderingContextOverloadsExtension external JSVoid bufferSubData( GLenum target, GLintptr dstByteOffset, - JSAny? srcData, [ + JSObject srcData, [ int srcOffset, GLuint length, ]); diff --git a/lib/src/dom/webgl_multi_draw.dart b/lib/src/dom/webgl_multi_draw.dart index 62ea67ba..2e9ea48e 100644 --- a/lib/src/dom/webgl_multi_draw.dart +++ b/lib/src/dom/webgl_multi_draw.dart @@ -13,39 +13,39 @@ class WEBGL_multi_draw implements JSObject {} extension WEBGLMultiDrawExtension on WEBGL_multi_draw { external JSVoid multiDrawArraysWEBGL( GLenum mode, - JSAny? firstsList, + JSObject firstsList, int firstsOffset, - JSAny? countsList, + JSObject countsList, int countsOffset, GLsizei drawcount, ); external JSVoid multiDrawElementsWEBGL( GLenum mode, - JSAny? countsList, + JSObject countsList, int countsOffset, GLenum type, - JSAny? offsetsList, + JSObject offsetsList, int offsetsOffset, GLsizei drawcount, ); external JSVoid multiDrawArraysInstancedWEBGL( GLenum mode, - JSAny? firstsList, + JSObject firstsList, int firstsOffset, - JSAny? countsList, + JSObject countsList, int countsOffset, - JSAny? instanceCountsList, + JSObject instanceCountsList, int instanceCountsOffset, GLsizei drawcount, ); external JSVoid multiDrawElementsInstancedWEBGL( GLenum mode, - JSAny? countsList, + JSObject countsList, int countsOffset, GLenum type, - JSAny? offsetsList, + JSObject offsetsList, int offsetsOffset, - JSAny? instanceCountsList, + JSObject instanceCountsList, int instanceCountsOffset, GLsizei drawcount, ); diff --git a/lib/src/dom/webgl_multi_draw_instanced_base_vertex_base_instance.dart b/lib/src/dom/webgl_multi_draw_instanced_base_vertex_base_instance.dart index 2af16804..440dc8e6 100644 --- a/lib/src/dom/webgl_multi_draw_instanced_base_vertex_base_instance.dart +++ b/lib/src/dom/webgl_multi_draw_instanced_base_vertex_base_instance.dart @@ -15,28 +15,28 @@ extension WEBGLMultiDrawInstancedBaseVertexBaseInstanceExtension on WEBGL_multi_draw_instanced_base_vertex_base_instance { external JSVoid multiDrawArraysInstancedBaseInstanceWEBGL( GLenum mode, - JSAny? firstsList, + JSObject firstsList, int firstsOffset, - JSAny? countsList, + JSObject countsList, int countsOffset, - JSAny? instanceCountsList, + JSObject instanceCountsList, int instanceCountsOffset, - JSAny? baseInstancesList, + JSObject baseInstancesList, int baseInstancesOffset, GLsizei drawcount, ); external JSVoid multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL( GLenum mode, - JSAny? countsList, + JSObject countsList, int countsOffset, GLenum type, - JSAny? offsetsList, + JSObject offsetsList, int offsetsOffset, - JSAny? instanceCountsList, + JSObject instanceCountsList, int instanceCountsOffset, - JSAny? baseVerticesList, + JSObject baseVerticesList, int baseVerticesOffset, - JSAny? baseInstancesList, + JSObject baseInstancesList, int baseInstancesOffset, GLsizei drawcount, ); diff --git a/lib/src/dom/webgpu.dart b/lib/src/dom/webgpu.dart index e6129c1e..5b4be46e 100644 --- a/lib/src/dom/webgpu.dart +++ b/lib/src/dom/webgpu.dart @@ -12,10 +12,10 @@ typedef GPUBufferUsageFlags = int; typedef GPUMapModeFlags = int; typedef GPUTextureUsageFlags = int; typedef GPUShaderStageFlags = int; -typedef GPUBindingResource = JSAny?; +typedef GPUBindingResource = JSObject; typedef GPUPipelineConstantValue = num; typedef GPUColorWriteFlags = int; -typedef GPUImageCopyExternalImageSource = JSAny?; +typedef GPUImageCopyExternalImageSource = JSObject; typedef GPUBufferDynamicOffset = int; typedef GPUStencilValue = int; typedef GPUSampleMask = int; @@ -29,10 +29,10 @@ typedef GPUSize64Out = int; typedef GPUIntegerCoordinateOut = int; typedef GPUSize32Out = int; typedef GPUFlagsConstant = int; -typedef GPUColor = JSAny?; -typedef GPUOrigin2D = JSAny?; -typedef GPUOrigin3D = JSAny?; -typedef GPUExtent3D = JSAny?; +typedef GPUColor = JSObject; +typedef GPUOrigin2D = JSObject; +typedef GPUOrigin3D = JSObject; +typedef GPUExtent3D = JSObject; typedef GPUPowerPreference = String; typedef GPUFeatureName = String; typedef GPUBufferMapState = String; @@ -434,15 +434,15 @@ class GPUExternalTexture implements GPUObjectBase {} @anonymous class GPUExternalTextureDescriptor implements GPUObjectDescriptorBase { external factory GPUExternalTextureDescriptor({ - required JSAny? source, + required JSObject source, PredefinedColorSpace colorSpace, }); } extension GPUExternalTextureDescriptorExtension on GPUExternalTextureDescriptor { - external set source(JSAny? value); - external JSAny? get source; + external set source(JSObject value); + external JSObject get source; external set colorSpace(PredefinedColorSpace value); external PredefinedColorSpace get colorSpace; } @@ -1300,7 +1300,7 @@ extension GPUBindingCommandsMixinExtension on GPUBindingCommandsMixin { external JSVoid setBindGroup( GPUIndex32 index, GPUBindGroup? bindGroup, [ - JSAny? dynamicOffsetsOrDynamicOffsetsData, + JSObject dynamicOffsetsOrDynamicOffsetsData, GPUSize64 dynamicOffsetsDataStart, GPUSize32 dynamicOffsetsDataLength, ]); @@ -1693,7 +1693,7 @@ extension GPUCanvasContextExtension on GPUCanvasContext { external JSVoid configure(GPUCanvasConfiguration configuration); external JSVoid unconfigure(); external GPUTexture getCurrentTexture(); - external JSAny? get canvas; + external JSObject get canvas; } @JS() diff --git a/lib/src/dom/webidl.dart b/lib/src/dom/webidl.dart index 7927d145..3060b498 100644 --- a/lib/src/dom/webidl.dart +++ b/lib/src/dom/webidl.dart @@ -4,9 +4,9 @@ import 'dart:js_interop'; -typedef ArrayBufferView = JSAny?; -typedef BufferSource = JSAny?; -typedef AllowSharedBufferSource = JSAny?; +typedef ArrayBufferView = JSObject; +typedef BufferSource = JSObject; +typedef AllowSharedBufferSource = JSObject; typedef VoidFunction = JSFunction; @JS('DOMException') diff --git a/lib/src/dom/webnn.dart b/lib/src/dom/webnn.dart index 6651a161..303b0911 100644 --- a/lib/src/dom/webnn.dart +++ b/lib/src/dom/webnn.dart @@ -7,10 +7,10 @@ import 'dart:js_interop'; import 'webgpu.dart'; typedef MLNamedArrayBufferViews = JSAny?; -typedef MLGPUResource = JSAny?; +typedef MLGPUResource = JSObject; typedef MLNamedGPUResources = JSAny?; typedef MLNamedOperands = JSAny?; -typedef MLBufferView = JSAny?; +typedef MLBufferView = JSObject; typedef MLDeviceType = String; typedef MLPowerPreference = String; typedef MLInputOperandLayout = String; @@ -55,8 +55,8 @@ extension MLContextOptionsExtension on MLContextOptions { class ML implements JSObject {} extension MLExtension on ML { - external JSPromise createContext([JSAny? gpuDeviceOrOptions]); - external MLContext createContextSync([JSAny? gpuDeviceOrOptions]); + external JSPromise createContext([JSObject gpuDeviceOrOptions]); + external MLContext createContextSync([JSObject gpuDeviceOrOptions]); } @JS('MLGraph') @@ -180,8 +180,8 @@ extension MLGraphBuilderExtension on MLGraphBuilder { MLOperand variance, [ MLBatchNormalizationOptions options, ]); - external JSAny? clamp([ - JSAny? operandOrOptions, + external JSObject clamp([ + JSObject operandOrOptions, MLClampOptions options, ]); external MLOperand concat( @@ -235,8 +235,8 @@ extension MLGraphBuilderExtension on MLGraphBuilder { external MLOperand neg(MLOperand input); external MLOperand sin(MLOperand input); external MLOperand tan(MLOperand input); - external JSAny? elu([ - JSAny? inputOrOptions, + external JSObject elu([ + JSObject inputOrOptions, MLEluOptions options, ]); external MLOperand gemm( @@ -260,21 +260,21 @@ extension MLGraphBuilderExtension on MLGraphBuilder { int hiddenSize, [ MLGruCellOptions options, ]); - external JSAny? hardSigmoid([ - JSAny? inputOrOptions, + external JSObject hardSigmoid([ + JSObject inputOrOptions, MLHardSigmoidOptions options, ]); - external JSAny? hardSwish([MLOperand input]); + external JSObject hardSwish([MLOperand input]); external MLOperand instanceNormalization( MLOperand input, [ MLInstanceNormalizationOptions options, ]); - external JSAny? leakyRelu([ - JSAny? inputOrOptions, + external JSObject leakyRelu([ + JSObject inputOrOptions, MLLeakyReluOptions options, ]); - external JSAny? linear([ - JSAny? inputOrOptions, + external JSObject linear([ + JSObject inputOrOptions, MLLinearOptions options, ]); external JSArray lstm( @@ -360,7 +360,7 @@ extension MLGraphBuilderExtension on MLGraphBuilder { MLOperand input, [ MLReduceOptions options, ]); - external JSAny? relu([MLOperand input]); + external JSObject relu([MLOperand input]); external MLOperand resample2d( MLOperand input, [ MLResample2dOptions options, @@ -369,18 +369,18 @@ extension MLGraphBuilderExtension on MLGraphBuilder { MLOperand input, JSArray newShape, ); - external JSAny? sigmoid([MLOperand input]); + external JSObject sigmoid([MLOperand input]); external MLOperand slice( MLOperand input, JSArray starts, JSArray sizes, ); - external JSAny? softmax([MLOperand input]); - external JSAny? softplus([ - JSAny? inputOrOptions, + external JSObject softmax([MLOperand input]); + external JSObject softplus([ + JSObject inputOrOptions, MLSoftplusOptions options, ]); - external JSAny? softsign([MLOperand input]); + external JSObject softsign([MLOperand input]); external JSArray split( MLOperand input, JSAny? splits, [ @@ -390,7 +390,7 @@ extension MLGraphBuilderExtension on MLGraphBuilder { MLOperand input, [ MLSqueezeOptions options, ]); - external JSAny? tanh([MLOperand input]); + external JSObject tanh([MLOperand input]); external MLOperand transpose( MLOperand input, [ MLTransposeOptions options, diff --git a/lib/src/dom/webrtc.dart b/lib/src/dom/webrtc.dart index 20e65d0b..0180c9e4 100644 --- a/lib/src/dom/webrtc.dart +++ b/lib/src/dom/webrtc.dart @@ -144,12 +144,12 @@ extension RTCPeerConnectionExtension on RTCPeerConnection { ]); external JSPromise getIdentityAssertion(); external JSPromise createOffer([ - JSAny? optionsOrSuccessCallback, + JSObject optionsOrSuccessCallback, RTCPeerConnectionErrorCallback failureCallback, RTCOfferOptions options, ]); external JSPromise createAnswer([ - JSAny? optionsOrSuccessCallback, + JSObject optionsOrSuccessCallback, RTCPeerConnectionErrorCallback failureCallback, ]); external JSPromise setLocalDescription([ diff --git a/lib/src/dom/webrtc_encoded_transform.dart b/lib/src/dom/webrtc_encoded_transform.dart index 2feb9ebe..f08e8e61 100644 --- a/lib/src/dom/webrtc_encoded_transform.dart +++ b/lib/src/dom/webrtc_encoded_transform.dart @@ -9,7 +9,7 @@ import 'html.dart'; import 'streams.dart'; import 'webcryptoapi.dart'; -typedef RTCRtpTransform = JSAny?; +typedef RTCRtpTransform = JSObject; typedef SmallCryptoKeyID = int; typedef CryptoKeyID = JSAny?; typedef SFrameTransformRole = String; diff --git a/lib/src/dom/webxr.dart b/lib/src/dom/webxr.dart index 08924dc4..59982e8b 100644 --- a/lib/src/dom/webxr.dart +++ b/lib/src/dom/webxr.dart @@ -21,7 +21,7 @@ import 'webxr_hand_input.dart'; import 'webxr_hit_test.dart'; import 'webxr_lighting_estimation.dart'; -typedef XRWebGLRenderingContext = JSAny?; +typedef XRWebGLRenderingContext = JSObject; typedef XRFrameRequestCallback = JSFunction; typedef XRSessionMode = String; typedef XRVisibilityState = String; diff --git a/lib/src/dom/webxr_hit_test.dart b/lib/src/dom/webxr_hit_test.dart index 672c1835..f014f880 100644 --- a/lib/src/dom/webxr_hit_test.dart +++ b/lib/src/dom/webxr_hit_test.dart @@ -113,7 +113,7 @@ extension XRRayDirectionInitExtension on XRRayDirectionInit { @staticInterop class XRRay implements JSObject { external factory XRRay([ - JSAny? originOrTransform, + JSObject originOrTransform, XRRayDirectionInit direction, ]); } diff --git a/pubspec.yaml b/pubspec.yaml index d6f65f87..ddaeb680 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: web description: >- Lightweight DOM and JS bindings built around JS static interop. -version: 0.3.0 +version: 0.3.1-dev repository: https://github.com/dart-lang/web @@ -9,6 +9,7 @@ environment: sdk: ">=3.2.0-194.0.dev <4.0.0" dev_dependencies: + analyzer: ^6.2.0 args: ^2.4.0 code_builder: ^4.4.0 dart_flutter_team_lints: ^2.0.0 diff --git a/tool/bindings_generator/generate_bindings.dart b/tool/bindings_generator/generate_bindings.dart index 498c91a2..6efea3b2 100644 --- a/tool/bindings_generator/generate_bindings.dart +++ b/tool/bindings_generator/generate_bindings.dart @@ -55,5 +55,6 @@ Future<TranslationResult> generateBindings( final ast = entry[1] as JSArray; translator.collect(shortname, ast); } + translator.setOrUpdateInterfacelikes(); return translator.translate(); } diff --git a/tool/bindings_generator/js_type_hierarchy.dart b/tool/bindings_generator/js_type_hierarchy.dart new file mode 100644 index 00000000..0fb095f7 --- /dev/null +++ b/tool/bindings_generator/js_type_hierarchy.dart @@ -0,0 +1,32 @@ +// 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. + +// Updated by /tool/update_bindings.dart. Do not modify by hand. + +const Map<String, Set<String>> jsTypeHierarchy = { + 'JSAny': {}, + 'JSObject': {'JSAny'}, + 'JSFunction': {'JSObject'}, + 'JSExportedDartFunction': {'JSFunction'}, + 'JSPromise': {'JSObject'}, + 'JSArray': {'JSObject'}, + 'JSBoxedDartObject': {'JSObject'}, + 'JSArrayBuffer': {'JSObject'}, + 'JSDataView': {'JSObject'}, + 'JSTypedArray': {'JSObject'}, + 'JSInt8Array': {'JSTypedArray'}, + 'JSUint8Array': {'JSTypedArray'}, + 'JSUint8ClampedArray': {'JSTypedArray'}, + 'JSInt16Array': {'JSTypedArray'}, + 'JSUint16Array': {'JSTypedArray'}, + 'JSInt32Array': {'JSTypedArray'}, + 'JSUint32Array': {'JSTypedArray'}, + 'JSFloat32Array': {'JSTypedArray'}, + 'JSFloat64Array': {'JSTypedArray'}, + 'JSNumber': {'JSAny'}, + 'JSBoolean': {'JSAny'}, + 'JSString': {'JSAny'}, + 'JSSymbol': {'JSAny'}, + 'JSBigInt': {'JSAny'} +}; diff --git a/tool/bindings_generator/translator.dart b/tool/bindings_generator/translator.dart index f880ec4b..cce30c05 100644 --- a/tool/bindings_generator/translator.dart +++ b/tool/bindings_generator/translator.dart @@ -8,6 +8,7 @@ import 'package:code_builder/code_builder.dart' as code; import 'package:path/path.dart' as p; import 'banned_names.dart'; +import 'js_type_hierarchy.dart'; import 'singletons.dart'; import 'type_aliases.dart'; import 'util.dart'; @@ -19,6 +20,7 @@ class _Library { final Translator translator; final String url; final List<idl.Interfacelike> interfacelikes = []; + final List<idl.Interfacelike> partialInterfacelikes = []; final List<idl.Typedef> typedefs = []; final List<idl.Enum> enums = []; final List<idl.Callback> callbacks = []; @@ -31,11 +33,14 @@ class _Library { final name = named.name.toDart; assert(!translator._typeToLibrary.containsKey(name)); translator._typeToLibrary[named.name.toDart] = this; + translator._typeToDeclaration[named.name.toDart] = node; list.add(named); } void add(idl.Node node) { final type = node.type.toDart; + // TODO(srujzs): We may want an enum here, but that would be slower due to + // a string lookup in the set of enums. switch (type) { case 'interface mixin': case 'interface': @@ -48,8 +53,9 @@ class _Library { final interfacelike = node as idl.Interfacelike; if (!node.partial.toDart) { _addNamed<idl.Interfacelike>(node, interfacelikes); + } else { + partialInterfacelikes.add(interfacelike); } - translator.setOrUpdateInterfacelike(interfacelike); break; case 'typedef': _addNamed<idl.Typedef>(node, typedefs); @@ -80,19 +86,112 @@ class _Library { } } -String _typeRaw(idl.IDLType idlType) { - final String type; +(String, bool) _computeJsTypeUnion( + (String, bool) rawType1, (String, bool) rawType2) { + if (rawType1.$1 == rawType2.$1) { + return (rawType1.$1, rawType1.$2 || rawType2.$2); + } + // In the case of unions, we should try and get a JS type-able type to get a + // better LUB. + (String, bool) getTypeForUnionCalculation((String, bool) rawType) { + var (type, nullable) = rawType; + final decl = Translator.instance!._typeToDeclaration[type]; + if (decl != null) { + final nodeType = decl.type.toDart; + switch (nodeType) { + case 'interface': + case 'dictionary': + // TODO(srujzs): We can do better if we do a LUB of the interfaces (so + // we get a possible interface name instead of `JSObject`), but that + // might be too much effort for too little reward. This would entail + // caching the hierarchy of IDL types. + type = 'JSObject'; + break; + case 'typedef': + final desugared = _typeRaw((decl as idl.Typedef).idlType); + type = desugared.$1; + nullable = desugared.$2; + break; + case 'callback': + type = 'JSFunction'; + break; + case 'enum': + type = 'JSString'; + break; + default: + throw Exception('Unhandled type $type with node type: $nodeType'); + } + } + return (type, nullable); + } + + var (type1, nullable1) = getTypeForUnionCalculation(rawType1); + var (type2, nullable2) = getTypeForUnionCalculation(rawType2); + final nullable = nullable1 || nullable2; + if (!jsTypeHierarchy.containsKey(type1) || + !jsTypeHierarchy.containsKey(type2)) { + return ('JSAny', nullable); + } + // Compute path from root and find the last type that exists in both paths for + // a least upper bound. + final t1Supertypes = [type1]; + final t2Supertypes = [type2]; + while (jsTypeHierarchy[type1]!.isNotEmpty) { + type1 = jsTypeHierarchy[type1]!.single; + t1Supertypes.add(type1); + } + while (jsTypeHierarchy[type2]!.isNotEmpty) { + type2 = jsTypeHierarchy[type2]!.single; + t2Supertypes.add(type2); + } + var t1i = t1Supertypes.length - 1; + var t2i = t2Supertypes.length - 1; + while (t1i >= 0 && t2i >= 0) { + if (t1Supertypes[t1i] != t2Supertypes[t2i]) break; + t1i--; + t2i--; + } + return (t1Supertypes[t1i + 1], nullable); +} + +/// Returns a record containing the Dart type for the given [idlType] and a bool +/// indicating whether the type is nullable. +(String, bool) _typeRaw(idl.IDLType idlType) { + // For union types, we take the possible union of all the types using a LUB. if (idlType.union.toDart) { - type = 'union'; - } else if (idlType.generic.toDart.isNotEmpty) { + final types = (idlType.idlType as JSArray).toDart; + String? unionType; + var nullable = idlType.nullable.toDart; + for (final type in types) { + final rawType = _typeRaw(type as idl.IDLType); + if (unionType == null) { + unionType = rawType.$1; + nullable |= rawType.$2; + } else { + final union = _computeJsTypeUnion((unionType, nullable), rawType); + unionType = union.$1; + nullable = union.$2; + } + } + return (unionType!, nullable); + } + final String type; + final nullable = idlType.nullable.toDart; + if (idlType.generic.toDart.isNotEmpty) { + // TODO(srujzs): Once we have a generic `JSArray` and `JSPromise`, we should + // add these type parameters in. We need to be careful, however, as we + // should only add the type parameter if the type is a subtype of `JSAny?` + // either because it is an interface or a typedef. We also need to make sure + // to convert type aliases that are Dart types back to JS types e.g. + // `String` should be `JSString`. type = idlType.generic.toDart; } else { type = (idlType.idlType as JSString).toDart; } if (typeAliases.containsKey(type)) { - return typeAliases[type]!; + return (typeAliases[type]!, nullable); } else { - return type; + return (type, nullable); } } @@ -102,19 +201,15 @@ class _Type { _Type._(this.type, this.isNullable); - factory _Type(idl.IDLType type) => - _Type._(_typeRaw(type), type.nullable.toDart); + factory _Type(idl.IDLType type) { + final (rawType, nullable) = _typeRaw(type); + return _Type._(rawType, nullable); + } void update(idl.IDLType idlType) { - final thatType = _typeRaw(idlType); - if (type != thatType) { - // TODO(joshualitt): In some cases we could probably find a better upper - // bound. - type = 'JSAny'; - } - if (idlType.nullable.toDart) { - isNullable = true; - } + final union = _computeJsTypeUnion((type, isNullable), _typeRaw(idlType)); + type = union.$1; + isNullable = union.$2; } } @@ -318,6 +413,7 @@ class _MemberName { class Translator { final _libraries = <String, _Library>{}; + final _typeToDeclaration = <String, idl.Node>{}; final _typeToLibrary = <String, _Library>{}; final _interfacelikes = <String, _PartialInterfacelike>{}; final _includes = <idl.Includes>[]; @@ -325,14 +421,32 @@ class Translator { late String _currentlyTranslatingUrl; final List<String> _cssStyleDeclarations; - Translator(this._librarySubDir, this._cssStyleDeclarations); + /// Singleton so that various helper methods can access info about the AST. + static Translator? instance; - void setOrUpdateInterfacelike(idl.Interfacelike interfacelike) { - final name = interfacelike.name.toDart; - if (_interfacelikes.containsKey(name)) { - _interfacelikes[name]!.update(interfacelike); - } else { - _interfacelikes[name] = _PartialInterfacelike(interfacelike); + Translator(this._librarySubDir, this._cssStyleDeclarations) { + instance = this; + } + + /// Set or update partial interfaces so we can have a unified interface + /// representation. + /// + /// Note that this is done after the initial pass on the AST. This is because + /// this step resolves unions and therefore can't be done until we record all + /// types. + void setOrUpdateInterfacelikes() { + for (final library in _libraries.values) { + for (final interfacelike in [ + ...library.interfacelikes, + ...library.partialInterfacelikes + ]) { + final name = interfacelike.name.toDart; + if (_interfacelikes.containsKey(name)) { + _interfacelikes[name]!.update(interfacelike); + } else { + _interfacelikes[name] = _PartialInterfacelike(interfacelike); + } + } } } @@ -346,10 +460,10 @@ class Translator { } } - code.TypeDef _typedef(String name, String type, bool nullable) => + code.TypeDef _typedef(String name, (String, bool) rawType) => code.TypeDef((b) => b ..name = name - ..definition = _typeReference(type, isNullable: nullable)); + ..definition = _typeReference(rawType.$1, isNullable: rawType.$2)); code.Method _topLevelGetter(String dartName, String getterName) => code.Method((b) => b @@ -399,9 +513,10 @@ class Translator { } code.TypeReference _idlTypeToTypeReference(idl.IDLType idlType, - {required bool isReturn}) => - _typeReference(_typeRaw(idlType), - isNullable: idlType.nullable.toDart, isReturn: isReturn); + {required bool isReturn}) { + final type = _typeRaw(idlType); + return _typeReference(type.$1, isNullable: type.$2, isReturn: isReturn); + } code.TypeReference _typeToTypeReference(_Type type, {required bool isReturn}) => @@ -675,19 +790,18 @@ class Translator { ..comments.addAll(licenseHeader) ..body.addAll([ for (final typedef in library.typedefs) - _typedef(typedef.name.toDart, _typeRaw(typedef.idlType), - typedef.idlType.nullable.toDart), + _typedef(typedef.name.toDart, _typeRaw(typedef.idlType)), // TODO(joshualitt): We should lower callbacks and callback interfaces to // a Dart function that takes a typed Dart function, and returns an // JSFunction. for (final callback in library.callbacks) - _typedef(callback.name.toDart, 'JSFunction', false), + _typedef(callback.name.toDart, ('JSFunction', false)), for (final callbackInterface in library.callbackInterfaces) - _typedef(callbackInterface.name.toDart, 'JSFunction', false), + _typedef(callbackInterface.name.toDart, ('JSFunction', false)), // TODO(joshualitt): Enums in the WebIDL are just strings, but we could // make them easier to work with on the Dart side. for (final enum_ in library.enums) - _typedef(enum_.name.toDart, 'String', false), + _typedef(enum_.name.toDart, ('String', false)), for (final interfacelike in library.interfacelikes) ..._interfacelike(interfacelike), ])); diff --git a/tool/bindings_generator/type_aliases.dart b/tool/bindings_generator/type_aliases.dart index b70ade87..cc187f04 100644 --- a/tool/bindings_generator/type_aliases.dart +++ b/tool/bindings_generator/type_aliases.dart @@ -4,7 +4,7 @@ const typeAliases = <String, String>{ 'any': 'JSAny', - 'union': 'JSAny', + 'bigint': 'JSBigInt', 'record': 'JSAny', 'object': 'JSObject', 'Promise': 'JSPromise', @@ -12,6 +12,7 @@ const typeAliases = <String, String>{ 'undefined': 'JSUndefined', 'Function': 'JSFunction', 'WindowProxy': 'Window', + 'SharedArrayBuffer': 'JSObject', 'ArrayBuffer': 'JSArrayBuffer', 'DataView': 'JSDataView', @@ -24,12 +25,18 @@ const typeAliases = <String, String>{ 'Uint8ClampedArray': 'JSUint8ClampedArray', 'Float32Array': 'JSFloat32Array', 'Float64Array': 'JSFloat64Array', + // TODO(srujzs): Change these aliases if we add these two as JS types. + 'BigInt64Array': 'JSTypedArray', + 'BigUint64Array': 'JSTypedArray', // Array aliases. 'sequence': 'JSArray', 'FrozenArray': 'JSArray', 'ObservableArray': 'JSArray', + // TODO(srujzs): We should ideally use JS types everywhere, and only change + // to Dart types when we are translating. However, we need to figure out what + // to do for `int` vs `num` as they both map to `JSNumber`. // Number aliases. 'byte': 'int', 'octet': 'int', diff --git a/tool/update_bindings.dart b/tool/update_bindings.dart index 05652a26..740b4ac2 100644 --- a/tool/update_bindings.dart +++ b/tool/update_bindings.dart @@ -1,6 +1,14 @@ +// 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. + import 'dart:convert'; import 'dart:io'; +import 'package:analyzer/dart/analysis/analysis_context_collection.dart'; +import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; import 'package:args/args.dart'; import 'package:io/ansi.dart' as ansi; import 'package:io/io.dart'; @@ -34,6 +42,9 @@ $_usage'''); await _runProc('npm', ['install'], _bindingsGeneratorPath); } + // Compute JS type hierarchy for union calculation in translator. + await _generateJsTypeHierarchy(); + if (argResult['compile'] as bool) { // Compile Dart to Javascript. await _runProc( @@ -131,6 +142,68 @@ Future<void> _runProc( } } +Future<void> _generateJsTypeHierarchy() async { + // Use a file that uses `dart:js_interop` for analysis. + final contextCollection = AnalysisContextCollection( + includedPaths: [p.fromUri(Platform.script.resolve('../lib/web.dart'))]); + final dartJsInterop = await contextCollection.contexts.single.currentSession + .getLibraryByUri('dart:js_interop') as LibraryElementResult; + final definedNames = dartJsInterop.element.exportNamespace.definedNames; + final jsTypeHierarchy = <String, Set<String>>{}; + for (final name in definedNames.keys) { + final element = definedNames[name]; + if (element is TypeDefiningElement) { + void storeSupertypes(InterfaceElement element) { + bool isInJsTypes(InterfaceElement element) => + // We only care about JS types for this calculation. + // TODO(srujzs): We'll likely need to change this once JS types move + // to extension types. + element.library.isInSdk && element.library.name == '_js_types'; + + if (!isInJsTypes(element)) return; + final supertypes = <String>{}; + final immediateSupertypes = <InterfaceType>[ + if (element.supertype != null) element.supertype!, + ...element.interfaces, + ]; + for (final supertype in immediateSupertypes) { + if (isInJsTypes(supertype.element)) { + supertypes.add("'${supertype.element.name}'"); + } + } + // Assert we have a tree hierarchy. + assert(supertypes.length == 1); + jsTypeHierarchy["'$name'"] = supertypes; + } + + if (element is TypeAliasElement) { + final type = element.aliasedType; + if (type is InterfaceType) storeSupertypes(type.element); + } else if (element is InterfaceElement) { + storeSupertypes(element); + } + } + } + + final jsTypeHierarchyScript = ''' + // 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. + + // Updated by $_thisScript. Do not modify by hand. + + const Map<String, Set<String>> jsTypeHierarchy = $jsTypeHierarchy; + '''; + final jsTypeHierarchyPath = + p.join(_bindingsGeneratorPath, 'js_type_hierarchy.dart'); + await File(jsTypeHierarchyPath).writeAsString(jsTypeHierarchyScript); + await _runProc( + Platform.executable, + ['format', jsTypeHierarchyPath], + _bindingsGeneratorPath, + ); +} + final _usage = ''' Usage: ${_parser.usage}''';