Skip to content

Commit 3e11172

Browse files
[interop] Add Support for Function Declarations (#392)
* Interop Gen: Support Function Declarations Fixes #389 * code resolution * changed primitive types from `enum` to `static const` types * minor changes * formatting * resolved code issues, added test cases, and refactored primitive type handling * Comment Resolution: - enum switch expression refactoring - other fixes * completed comment resolution
1 parent c0d73b5 commit 3e11172

17 files changed

+812
-289
lines changed

web_generator/lib/src/ast.dart

Lines changed: 0 additions & 169 deletions
This file was deleted.

web_generator/lib/src/ast/base.dart

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:code_builder/code_builder.dart';
6+
7+
import '../interop_gen/namer.dart';
8+
import 'types.dart';
9+
10+
class GlobalOptions {
11+
static int variardicArgsCount = 4;
12+
static bool shouldEmitJsTypes = false;
13+
}
14+
15+
class Options {}
16+
17+
// TODO(nikeokoronkwo): Remove this once we address isNullable
18+
class DeclarationOptions extends Options {
19+
DeclarationOptions();
20+
21+
TypeOptions toTypeOptions({bool nullable = false}) =>
22+
TypeOptions(nullable: nullable);
23+
}
24+
25+
class TypeOptions extends Options {
26+
bool nullable;
27+
28+
TypeOptions({this.nullable = false});
29+
}
30+
31+
class ASTOptions {
32+
bool parameter;
33+
bool emitJSTypes;
34+
int variardicArgsCount;
35+
36+
ASTOptions(
37+
{this.parameter = false,
38+
this.variardicArgsCount = 4,
39+
this.emitJSTypes = false});
40+
}
41+
42+
sealed class Node {
43+
abstract final String? name;
44+
abstract final ID id;
45+
String? get dartName;
46+
47+
Spec emit([Options? options]);
48+
49+
Node();
50+
}
51+
52+
abstract class Declaration extends Node {
53+
@override
54+
abstract final String name;
55+
56+
@override
57+
Spec emit([covariant DeclarationOptions? options]);
58+
}
59+
60+
abstract class NamedDeclaration extends Declaration {
61+
ReferredType asReferredType([List<Type>? typeArgs]) =>
62+
ReferredType(name: name, declaration: this, typeParams: typeArgs ?? []);
63+
}
64+
65+
abstract interface class ExportableDeclaration extends Declaration {
66+
/// Whether this declaration is exported.
67+
bool get exported;
68+
}
69+
70+
abstract class Type extends Node {
71+
@override
72+
String? dartName;
73+
74+
@override
75+
Reference emit([covariant TypeOptions? options]);
76+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// ignore_for_file: non_constant_identifier_names
6+
7+
import 'package:code_builder/code_builder.dart';
8+
9+
import '../interop_gen/namer.dart';
10+
import 'base.dart';
11+
12+
/// A built in type supported by `dart:js_interop` or by this library
13+
/// (with generated declarations)
14+
class BuiltinType extends Type {
15+
@override
16+
final String name;
17+
18+
final List<Type> typeParams;
19+
20+
/// Whether the given type is present in "dart:js_interop"
21+
final bool fromDartJSInterop;
22+
23+
// TODO(nikeokoronkwo): Types in general should have an `isNullable`
24+
// property on them to indicate nullability for Dart generated code.
25+
final bool? isNullable;
26+
27+
BuiltinType(
28+
{required this.name,
29+
this.typeParams = const [],
30+
this.fromDartJSInterop = false,
31+
this.isNullable});
32+
33+
@override
34+
ID get id => ID(type: 'type', name: name);
35+
36+
@override
37+
String? get dartName => null;
38+
39+
@override
40+
Reference emit([TypeOptions? options]) {
41+
options ??= TypeOptions();
42+
43+
return TypeReference((t) => t
44+
..symbol = name
45+
..types.addAll(typeParams
46+
// if there is only one type param, and it is void, ignore
47+
.where((p) => typeParams.length != 1 || p != $voidType)
48+
.map((p) => p.emit(TypeOptions())))
49+
..url = fromDartJSInterop ? 'dart:js_interop' : null
50+
..isNullable = isNullable ?? options!.nullable);
51+
}
52+
53+
static final BuiltinType $voidType = BuiltinType(name: 'void');
54+
static final BuiltinType anyType =
55+
BuiltinType(name: 'JSAny', fromDartJSInterop: true, isNullable: true);
56+
57+
static BuiltinType primitiveType(PrimitiveType typeIdentifier,
58+
{bool? shouldEmitJsType,
59+
bool? isNullable,
60+
List<Type> typeParams = const []}) {
61+
shouldEmitJsType ??= GlobalOptions.shouldEmitJsTypes;
62+
return switch (typeIdentifier) {
63+
PrimitiveType.int ||
64+
PrimitiveType.num ||
65+
PrimitiveType.double when shouldEmitJsType =>
66+
BuiltinType(
67+
name: 'JSNumber', fromDartJSInterop: true, isNullable: isNullable),
68+
PrimitiveType.int => BuiltinType(name: 'int', isNullable: isNullable),
69+
PrimitiveType.num => BuiltinType(name: 'num', isNullable: isNullable),
70+
PrimitiveType.double =>
71+
BuiltinType(name: 'double', isNullable: isNullable),
72+
PrimitiveType.boolean => shouldEmitJsType
73+
? BuiltinType(
74+
name: 'JSBoolean',
75+
fromDartJSInterop: true,
76+
isNullable: isNullable)
77+
: BuiltinType(name: 'bool', isNullable: isNullable),
78+
PrimitiveType.string => shouldEmitJsType
79+
? BuiltinType(
80+
name: 'JSString', fromDartJSInterop: true, isNullable: isNullable)
81+
: BuiltinType(name: 'String', isNullable: isNullable),
82+
PrimitiveType.$void || PrimitiveType.undefined => $voidType,
83+
PrimitiveType.any || PrimitiveType.unknown => anyType,
84+
PrimitiveType.object => BuiltinType(
85+
name: 'JSObject', fromDartJSInterop: true, isNullable: isNullable),
86+
PrimitiveType.array => BuiltinType(
87+
name: 'JSArray',
88+
typeParams: [typeParams.single],
89+
fromDartJSInterop: true,
90+
isNullable: isNullable),
91+
PrimitiveType.promise => BuiltinType(
92+
name: 'JSPromise',
93+
typeParams: [typeParams.single],
94+
fromDartJSInterop: true,
95+
isNullable: isNullable),
96+
PrimitiveType.function => BuiltinType(
97+
name: 'JSFunction', fromDartJSInterop: true, isNullable: isNullable),
98+
};
99+
}
100+
}
101+
102+
enum PrimitiveType {
103+
int,
104+
num,
105+
double,
106+
boolean,
107+
string,
108+
$void,
109+
any,
110+
object,
111+
unknown,
112+
undefined,
113+
array,
114+
promise,
115+
function
116+
}

0 commit comments

Comments
 (0)