Skip to content

[interop] Add support for importing and exporting declarations, as well as multi-file output #418

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 21 commits into from
Aug 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions web_generator/lib/src/ast/base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ class DeclarationOptions extends Options {

class TypeOptions extends Options {
bool nullable;
String? url;

TypeOptions({this.nullable = false});
TypeOptions({this.nullable = false, this.url});
}

class ASTOptions {
Expand All @@ -42,7 +43,7 @@ class ASTOptions {
}

sealed class Node {
abstract final String? name;
String? get name;
abstract final ID id;
String? get dartName;

Expand All @@ -53,20 +54,30 @@ sealed class Node {

abstract class Declaration extends Node {
@override
abstract final String name;
String get name;

@override
Spec emit([covariant DeclarationOptions? options]);
}

abstract class NamedDeclaration extends Declaration {
ReferredType asReferredType([List<Type>? typeArgs]) =>
ReferredType(name: name, declaration: this, typeParams: typeArgs ?? []);
@override
abstract String name;

ReferredType asReferredType([List<Type>? typeArgs, String? url]) =>
ReferredType(
name: name, declaration: this, typeParams: typeArgs ?? [], url: url);
}

abstract interface class ExportableDeclaration extends Declaration {
/// Whether this declaration is exported.
bool get exported;

@override
abstract String? dartName;

@override
abstract String name;
}

abstract class Type extends Node {
Expand Down
37 changes: 21 additions & 16 deletions web_generator/lib/src/ast/declarations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import 'types.dart';
sealed class TypeDeclaration extends NamedDeclaration
implements ExportableDeclaration {
@override
final String name;
String name;

@override
final String? dartName;
String? dartName;

@override
final bool exported;
Expand Down Expand Up @@ -139,6 +139,9 @@ class VariableDeclaration extends FieldDeclaration
@override
ID get id => ID(type: 'var', name: name);

@override
String? dartName;

@override
Spec emit([DeclarationOptions? options]) {
if (modifier == VariableModifier.$const) {
Expand All @@ -159,12 +162,10 @@ class VariableDeclaration extends FieldDeclaration
}

@override
String? get dartName => null;

@override
ReferredType<VariableDeclaration> asReferredType([List<Type>? typeArgs]) {
ReferredType<VariableDeclaration> asReferredType(
[List<Type>? typeArgs, String? url]) {
return ReferredType<VariableDeclaration>.fromType(type, this,
typeParams: typeArgs ?? []);
typeParams: typeArgs ?? [], url: url);
}
}

Expand All @@ -173,10 +174,10 @@ enum VariableModifier { let, $const, $var }
class FunctionDeclaration extends CallableDeclaration
implements ExportableDeclaration {
@override
final String name;
String name;

@override
final String? dartName;
String? dartName;

@override
final List<ParameterDeclaration> parameters;
Expand Down Expand Up @@ -234,18 +235,19 @@ class FunctionDeclaration extends CallableDeclaration
}

@override
ReferredType<FunctionDeclaration> asReferredType([List<Type>? typeArgs]) {
ReferredType<FunctionDeclaration> asReferredType(
[List<Type>? typeArgs, String? url]) {
// TODO: We could do better here and make the function type typed
return ReferredType<FunctionDeclaration>.fromType(
BuiltinType.referred('Function', typeParams: typeArgs ?? [])!, this,
typeParams: typeArgs ?? []);
typeParams: typeArgs ?? [], url: url);
}
}

class EnumDeclaration extends NamedDeclaration
implements ExportableDeclaration {
@override
final String name;
String name;

@override
final bool exported;
Expand Down Expand Up @@ -339,14 +341,14 @@ class EnumMember {
class TypeAliasDeclaration extends NamedDeclaration
implements ExportableDeclaration {
@override
final String name;
String name;

final List<GenericType> typeParameters;

final Type type;

@override
final String? dartName;
String? dartName;

@override
bool exported;
Expand Down Expand Up @@ -447,13 +449,13 @@ class InterfaceDeclaration extends TypeDeclaration {
class PropertyDeclaration extends FieldDeclaration
implements MemberDeclaration {
@override
final String name;
String name;

@override
final ID id;

@override
final String? dartName;
String? dartName;

@override
late final TypeDeclaration parent;
Expand Down Expand Up @@ -696,6 +698,9 @@ class OperatorDeclaration extends CallableDeclaration
@override
String get name => kind.expression;

@override
set name(String? name) {}

OperatorKind kind;

@override
Expand Down
19 changes: 13 additions & 6 deletions web_generator/lib/src/ast/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,24 @@ class ReferredType<T extends Declaration> extends Type {

List<Type> typeParams;

String? url;

ReferredType(
{required this.name,
required this.declaration,
this.typeParams = const []});
this.typeParams = const [],
this.url});

factory ReferredType.fromType(Type type, T declaration,
{List<Type> typeParams}) = ReferredDeclarationType;
{List<Type> typeParams, String? url}) = ReferredDeclarationType;

@override
Reference emit([TypeOptions? options]) {
// TODO: Support referred types imported from URL
return TypeReference((t) => t
..symbol = declaration.name
..symbol = declaration.dartName ?? declaration.name
..types.addAll(typeParams.map((t) => t.emit(options)))
..isNullable = options?.nullable);
..isNullable = options?.nullable
..url = options?.url ?? url);
}
}

Expand All @@ -44,11 +47,15 @@ class ReferredDeclarationType<T extends Declaration> extends ReferredType<T> {
@override
String get name => type.name ?? declaration.name;

ReferredDeclarationType(this.type, T declaration, {super.typeParams})
ReferredDeclarationType(this.type, T declaration,
{super.typeParams, super.url})
: super(name: declaration.name, declaration: declaration);

@override
Reference emit([covariant TypeOptions? options]) {
options ??= TypeOptions();
options.url = super.url;

return type.emit(options);
}
}
Expand Down
5 changes: 4 additions & 1 deletion web_generator/lib/src/dart_main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ Future<void> generateJSInteropBindings(Config config) async {
final jsDeclarations = parseDeclarationFiles(config.input);

// transform declarations
final dartDeclarations = transform(jsDeclarations, config: config);
final manager =
TransformerManager.fromParsedResults(jsDeclarations, config: config);

final dartDeclarations = manager.transform();

// generate
final generatedCodeMap = dartDeclarations.generate(config);
Expand Down
Loading