Skip to content

[interop] Add Support for Anonymous Declarations #434

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Aug 15, 2025

Conversation

nikeokoronkwo
Copy link
Collaborator

@nikeokoronkwo nikeokoronkwo commented Aug 2, 2025

Fixes #385
Fixes #422
Fixes #410
Fixes #433

This PR adds support for generating declarations for anonymous declarations, such as anonymous objects, unions, closures and constructor types.

This PR also adds support for nullable types (types unioned with undefined and/or null).

A hashing function is used for consistently hashing string objects, which is used for hashing identifiers for anonymous unions, objects and more, as well as comparing such names to allow reusing of such types.

  • Anonymous Unions are turned into a Dart (anonymous) extension type which has a rep type/implements the shared type between the union parts. It has getters to get the value as a certain probability of the union. For instance, a union string | number | boolean may look like the following:
    extension type _AnonymousUnion_204398._(JSAny _) implements JSAny {
      String get asString => (_ as JSString).toDart;
      double get asDouble => (_ as JSNumber).toDartDouble;
      bool get asBool => (_ as JSBoolean).toDart;
    }
  • Anonymous Tuples are turned into an instance of a JSTupleX declaration generated depending on the number of members it may have (i.e if a 2 member tuple exists, it will be an instance of JSTuple2<A, B>). The tuple extension type looks like the following:
    // normal
    extension type JSTupleX<A, B, ..., B1>._(JSArray<JSAny> _) implements JSArray<JSAny> {
      A get $1 => _[0] as A;
      B get $2 => _[1] as B;
      /* ... */
      B1 get $x => _[x] as B1;
      
      set $1(A newValue) => _[0] = newValue;
      set $2(B newValue) => _[1] = newValue;
      /* ... */
      set $x(B1 newValue) => _[x] = newValue;
    }
    
    // readonly
    extension type JSReadonlyTupleX<A, B, ..., B1>._(JSArray<JSAny> _) implements JSArray<JSAny> {
      A get $1 => _[0] as A;
      B get $2 => _[1] as B;
      /* ... */
      B1 get $x => _[x] as B1;
    }
  • Anonymous Closures are turned into extension types implementing call. While Anonymous function types ((str: string) => void) have their call implementations as external, anonymous constructor types (new (str: string) => T to construct T) are implemented as function calls to create the given object. In the future after Make JSExportedDartFunction generic and add a toJSGeneric function sdk#54557, we should be able to replace this with a generic JSFunction.
    extension type _AnonymousFunction_123456._(JSFunction _) implements JSFunction {
      external void call(String str);
    }
    
    // Assuming T is defined elsewhere and is **not** a generic
    extension type _AnonymousFunction_123456._(JSFunction _) implements JSFunction {
      T call(String str) => T(str);
    }
  • Anonymous Objects are implemented as extension type objects with their default constructor as an object literal constructor. They also inherit any associated generic types alongside.

@nikeokoronkwo nikeokoronkwo marked this pull request as ready for review August 7, 2025 00:48
@nikeokoronkwo nikeokoronkwo requested a review from srujzs August 7, 2025 05:39
Copy link
Contributor

@srujzs srujzs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Nike! Just a couple more comments.

@srujzs
Copy link
Contributor

srujzs commented Aug 12, 2025

Sorry, GitHub UI is atrocious and didn't show me all the unresolved comments in the commits tab so I have a few more. :)

Copy link
Contributor

@srujzs srujzs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just some small nits around prints.

nikeokoronkwo and others added 3 commits August 14, 2025 23:01
# Conflicts:
#	web_generator/lib/src/ast/base.dart
#	web_generator/lib/src/ast/declarations.dart
#	web_generator/lib/src/interop_gen/transform/transformer.dart
#	web_generator/test/integration/interop_gen/project/output/c.dart
@nikeokoronkwo nikeokoronkwo merged commit 779d005 into dart-lang:main Aug 15, 2025
8 checks passed
@nikeokoronkwo nikeokoronkwo deleted the interop/anonymous branch August 15, 2025 01:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Interop Gen: Support Tuples Interop Gen: Support Function Types Interop Gen: Support Constructor Types Interop Gen: Support Union Types
2 participants