From a5678f5b880e7239827a31a81d7bcc3219874316 Mon Sep 17 00:00:00 2001 From: Srujan Gaddam Date: Tue, 5 Dec 2023 13:10:47 -0800 Subject: [PATCH 1/3] Handle Dart SDK change to extension types This is to make sure code generation doesn't break when we move JS types to extension types. Moving all of the types defined in web.dart to extension types will be handled in a future change. Updates analyzer dep to 6.3.0 to get the latest extension type changes. --- pubspec.yaml | 2 +- .../js_type_supertypes.dart | 30 +++++++++---------- tool/update_bindings.dart | 26 ++++++++++------ 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index a68aa027..493593f9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,7 +8,7 @@ environment: sdk: ^3.2.0 dev_dependencies: - analyzer: ^6.2.0 + analyzer: ^6.3.0 args: ^2.4.0 build_runner: ^2.4.0 build_web_compilers: ^4.0.7 diff --git a/tool/bindings_generator/js_type_supertypes.dart b/tool/bindings_generator/js_type_supertypes.dart index 56fd79b0..312e9d7e 100644 --- a/tool/bindings_generator/js_type_supertypes.dart +++ b/tool/bindings_generator/js_type_supertypes.dart @@ -6,27 +6,27 @@ const Map jsTypeSupertypes = { 'JSAny': null, - 'JSObject': 'JSAny', - 'JSFunction': 'JSObject', - 'JSExportedDartFunction': 'JSFunction', - 'JSPromise': 'JSObject', 'JSArray': 'JSObject', - 'JSBoxedDartObject': 'JSObject', 'JSArrayBuffer': 'JSObject', + 'JSBigInt': 'JSAny', + 'JSBoolean': 'JSAny', + 'JSBoxedDartObject': 'JSObject', 'JSDataView': 'JSObject', - 'JSTypedArray': 'JSObject', - 'JSInt8Array': 'JSTypedArray', - 'JSUint8Array': 'JSTypedArray', - 'JSUint8ClampedArray': 'JSTypedArray', - 'JSInt16Array': 'JSTypedArray', - 'JSUint16Array': 'JSTypedArray', - 'JSInt32Array': 'JSTypedArray', - 'JSUint32Array': 'JSTypedArray', + 'JSExportedDartFunction': 'JSFunction', 'JSFloat32Array': 'JSTypedArray', 'JSFloat64Array': 'JSTypedArray', + 'JSFunction': 'JSObject', + 'JSInt16Array': 'JSTypedArray', + 'JSInt32Array': 'JSTypedArray', + 'JSInt8Array': 'JSTypedArray', 'JSNumber': 'JSAny', - 'JSBoolean': 'JSAny', + 'JSObject': 'JSAny', + 'JSPromise': 'JSObject', 'JSString': 'JSAny', 'JSSymbol': 'JSAny', - 'JSBigInt': 'JSAny' + 'JSTypedArray': 'JSObject', + 'JSUint16Array': 'JSTypedArray', + 'JSUint32Array': 'JSTypedArray', + 'JSUint8Array': 'JSTypedArray', + 'JSUint8ClampedArray': 'JSTypedArray' }; diff --git a/tool/update_bindings.dart b/tool/update_bindings.dart index 3aa8114f..b6a9a4b6 100644 --- a/tool/update_bindings.dart +++ b/tool/update_bindings.dart @@ -2,6 +2,7 @@ // 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:collection'; import 'dart:convert'; import 'dart:io'; @@ -175,28 +176,35 @@ Future _generateJsTypeSupertypes() async { final dartJsInterop = await contextCollection.contexts.single.currentSession .getLibraryByUri('dart:js_interop') as LibraryElementResult; final definedNames = dartJsInterop.element.exportNamespace.definedNames; - final jsTypeSupertypes = {}; + // `SplayTreeMap` to avoid moving types around in `dart:js_interop` affecting + // the code generation. + final jsTypeSupertypes = SplayTreeMap(); for (final name in definedNames.keys) { final element = definedNames[name]; if (element is TypeDefiningElement) { + // TODO(srujzs): This contains code that handles the SDK before and after + // the migration of JS types to extension types. Once the changes to + // migrate to extension types hit the dev branch, we should remove some of + // the old code. void storeSupertypes(InterfaceElement element) { - bool isInJsTypes(InterfaceElement element) => + bool isInJsTypesOrJsInterop(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'; + element.library.isInSdk && + (element.library.name == '_js_types' || + element is ExtensionTypeElement && + element.library.name == 'dart.js_interop'); - if (!isInJsTypes(element)) return; + if (!isInJsTypesOrJsInterop(element)) return; String? parentJsType; final supertype = element.supertype; final immediateSupertypes = [ - if (supertype != null && !supertype.isDartCoreObject) supertype, + if (supertype != null) supertype, ...element.interfaces, - ]; + ]..removeWhere((supertype) => supertype.isDartCoreObject); // We should have at most one non-trivial supertype. assert(immediateSupertypes.length <= 1); for (final supertype in immediateSupertypes) { - if (isInJsTypes(supertype.element)) { + if (isInJsTypesOrJsInterop(supertype.element)) { parentJsType = "'${supertype.element.name}'"; } } From 769fad160858065492d509891db8cd7816003388 Mon Sep 17 00:00:00 2001 From: Srujan Gaddam Date: Tue, 5 Dec 2023 13:46:19 -0800 Subject: [PATCH 2/3] Move function to top-level --- tool/update_bindings.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tool/update_bindings.dart b/tool/update_bindings.dart index b6a9a4b6..2f4ef7cd 100644 --- a/tool/update_bindings.dart +++ b/tool/update_bindings.dart @@ -168,6 +168,13 @@ Future _runProc( } } +bool _isInJsTypesOrJsInterop(InterfaceElement element) => + // We only care about JS types for this calculation. + element.library.isInSdk && + (element.library.name == '_js_types' || + element is ExtensionTypeElement && + element.library.name == 'dart.js_interop'); + Future _generateJsTypeSupertypes() async { // Use a file that uses `dart:js_interop` for analysis. final contextCollection = AnalysisContextCollection(includedPaths: [ @@ -187,14 +194,7 @@ Future _generateJsTypeSupertypes() async { // migrate to extension types hit the dev branch, we should remove some of // the old code. void storeSupertypes(InterfaceElement element) { - bool isInJsTypesOrJsInterop(InterfaceElement element) => - // We only care about JS types for this calculation. - element.library.isInSdk && - (element.library.name == '_js_types' || - element is ExtensionTypeElement && - element.library.name == 'dart.js_interop'); - - if (!isInJsTypesOrJsInterop(element)) return; + if (!_isInJsTypesOrJsInterop(element)) return; String? parentJsType; final supertype = element.supertype; final immediateSupertypes = [ @@ -204,7 +204,7 @@ Future _generateJsTypeSupertypes() async { // We should have at most one non-trivial supertype. assert(immediateSupertypes.length <= 1); for (final supertype in immediateSupertypes) { - if (isInJsTypesOrJsInterop(supertype.element)) { + if (_isInJsTypesOrJsInterop(supertype.element)) { parentJsType = "'${supertype.element.name}'"; } } From 00d7e78c84cc923a33152e57e0705d8983bb6752 Mon Sep 17 00:00:00 2001 From: Srujan Gaddam Date: Tue, 5 Dec 2023 13:47:26 -0800 Subject: [PATCH 3/3] Remove unnecessary comment in _isInJsTypesOrJsInterop --- tool/update_bindings.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/tool/update_bindings.dart b/tool/update_bindings.dart index 2f4ef7cd..3f6a3559 100644 --- a/tool/update_bindings.dart +++ b/tool/update_bindings.dart @@ -169,7 +169,6 @@ Future _runProc( } bool _isInJsTypesOrJsInterop(InterfaceElement element) => - // We only care about JS types for this calculation. element.library.isInSdk && (element.library.name == '_js_types' || element is ExtensionTypeElement &&