From 9d7b33e8729e3883cafd9b26021afaf14b43f75a Mon Sep 17 00:00:00 2001 From: Srujan Gaddam <58529443+srujzs@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:41:20 -0800 Subject: [PATCH] Handle Dart SDK change to extension types (#116) * 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 | 29 +++++++++++------- 3 files changed, 34 insertions(+), 27 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..3f6a3559 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'; @@ -167,6 +168,12 @@ Future _runProc( } } +bool _isInJsTypesOrJsInterop(InterfaceElement element) => + 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: [ @@ -175,28 +182,28 @@ 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) => - // 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; + 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}'"; } }