Skip to content

Commit

Permalink
Handle Dart SDK change to extension types (#116)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
srujzs authored Dec 7, 2023
1 parent 0ae45ec commit 9d7b33e
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 27 deletions.
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 15 additions & 15 deletions tool/bindings_generator/js_type_supertypes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@

const Map<String, String?> 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'
};
29 changes: 18 additions & 11 deletions tool/update_bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -167,6 +168,12 @@ Future<void> _runProc(
}
}

bool _isInJsTypesOrJsInterop(InterfaceElement element) =>
element.library.isInSdk &&
(element.library.name == '_js_types' ||
element is ExtensionTypeElement &&
element.library.name == 'dart.js_interop');

Future<void> _generateJsTypeSupertypes() async {
// Use a file that uses `dart:js_interop` for analysis.
final contextCollection = AnalysisContextCollection(includedPaths: [
Expand All @@ -175,28 +182,28 @@ Future<void> _generateJsTypeSupertypes() async {
final dartJsInterop = await contextCollection.contexts.single.currentSession
.getLibraryByUri('dart:js_interop') as LibraryElementResult;
final definedNames = dartJsInterop.element.exportNamespace.definedNames;
final jsTypeSupertypes = <String, String?>{};
// `SplayTreeMap` to avoid moving types around in `dart:js_interop` affecting
// the code generation.
final jsTypeSupertypes = SplayTreeMap<String, String?>();
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 = <InterfaceType>[
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}'";
}
}
Expand Down

0 comments on commit 9d7b33e

Please sign in to comment.