From 4a1f7d8e38df0b8388ebca67fb9d59f93106f8a8 Mon Sep 17 00:00:00 2001 From: Nike Okoronkwo Date: Tue, 19 Aug 2025 22:54:17 -0500 Subject: [PATCH 1/2] Minor Fixes in Generics with Anonymous Closures --- web_generator/lib/src/ast/types.dart | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/web_generator/lib/src/ast/types.dart b/web_generator/lib/src/ast/types.dart index 5e5552a9..4bc6bb83 100644 --- a/web_generator/lib/src/ast/types.dart +++ b/web_generator/lib/src/ast/types.dart @@ -337,13 +337,24 @@ sealed class ClosureType extends DeclarationType { this.typeParameters = const [], this.parameters = const [], this.isNullable = false, - }) : declarationName = name; + }) : declarationName = name { + if (typeParameters.isEmpty) { + typeParameters.addAll(getGenericTypes(this).map((t) { + t.constraint ??= BuiltinType.anyType; + return t; + })); + } + } @override Reference emit([TypeOptions? options]) { return TypeReference((t) => t ..symbol = declarationName - ..isNullable = options?.nullable ?? isNullable); + ..isNullable = options?.nullable ?? isNullable + ..types.addAll(typeParameters.map((t) { + final clonedT = GenericType(name: t.name, isNullable: t.isNullable); + return clonedT.emit(options); + }))); } } @@ -388,8 +399,7 @@ class FunctionType extends ClosureType { name: 'call', id: const ID(type: 'fun', name: 'call'), returnType: returnType, - parameters: parameters, - typeParameters: typeParameters) + parameters: parameters) ]); } @@ -445,8 +455,6 @@ class _ConstructorDeclaration extends CallableDeclaration .addAll(typeParameters.map((t) => t.emit(options?.toTypeOptions()))) ..methods.add(Method((m) => m ..name = 'call' - ..types - .addAll(typeParameters.map((t) => t.emit(options?.toTypeOptions()))) ..returns = returnType.emit(options?.toTypeOptions()) ..requiredParameters.addAll(requiredParams) ..optionalParameters.addAll(optionalParams) From 0e229c62a0f158428c67219bdbc6d77a37f039fa Mon Sep 17 00:00:00 2001 From: Nikechukwu <150845642+nikeokoronkwo@users.noreply.github.com> Date: Wed, 20 Aug 2025 17:38:28 +0000 Subject: [PATCH 2/2] added test, and made generic type list a set --- web_generator/lib/src/ast/helpers.dart | 6 +++--- .../test/integration/interop_gen/ts_typing_expected.dart | 5 +++++ .../test/integration/interop_gen/ts_typing_input.d.ts | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/web_generator/lib/src/ast/helpers.dart b/web_generator/lib/src/ast/helpers.dart index 4d071e9c..f509c71d 100644 --- a/web_generator/lib/src/ast/helpers.dart +++ b/web_generator/lib/src/ast/helpers.dart @@ -160,8 +160,8 @@ Type getRepresentationType(TypeDeclaration td) { } /// Recursively get the generic types specified in a given type [t] -List getGenericTypes(Type t) { - final types = <(String, Type?)>[]; +Set getGenericTypes(Type t) { + final types = <(String, Type?)>{}; switch (t) { case GenericType(): types.add((t.name, t.constraint)); @@ -250,7 +250,7 @@ List getGenericTypes(Type t) { // Types are cloned so that modifications to constraints can happen without // affecting initial references - return types.map((t) => GenericType(name: t.$1, constraint: t.$2)).toList(); + return types.map((t) => GenericType(name: t.$1, constraint: t.$2)).toSet(); } Type desugarTypeAliases(Type t) { diff --git a/web_generator/test/integration/interop_gen/ts_typing_expected.dart b/web_generator/test/integration/interop_gen/ts_typing_expected.dart index 9962ca38..c583c9bc 100644 --- a/web_generator/test/integration/interop_gen/ts_typing_expected.dart +++ b/web_generator/test/integration/interop_gen/ts_typing_expected.dart @@ -33,6 +33,7 @@ extension type const MyEnum._(int _) { static const MyEnum D = MyEnum._(4); } +typedef Transformer = _AnonymousFunction_5293571; @_i1.JS() external _i1.JSFunction copyOfmyEnclosingFunction; @_i1.JS() @@ -112,6 +113,10 @@ extension type AnonymousType_9143117._(_i1.JSObject _) external T value; } +extension type _AnonymousFunction_5293571._( + _i1.JSFunction _) implements _i1.JSFunction { + external ComposedType call(T object); +} extension type ComposedType._(_i1.JSObject _) implements _i1.JSObject { external T enclosed; diff --git a/web_generator/test/integration/interop_gen/ts_typing_input.d.ts b/web_generator/test/integration/interop_gen/ts_typing_input.d.ts index b47a6cce..713db27d 100644 --- a/web_generator/test/integration/interop_gen/ts_typing_input.d.ts +++ b/web_generator/test/integration/interop_gen/ts_typing_input.d.ts @@ -11,6 +11,7 @@ export declare enum MyEnum { interface ComposedType { enclosed: T; } +export type Transformer = (object: T) => ComposedType; export declare let copyOfmyEnclosingFunction: typeof myEnclosingFunction; export declare const myEnumValue: MyEnum; export declare const myEnumValue2: typeof MyEnum;