5
5
import 'package:code_builder/code_builder.dart' ;
6
6
import '../interop_gen/namer.dart' ;
7
7
import 'base.dart' ;
8
+ import 'builtin.dart' ;
9
+ import 'declarations.dart' ;
8
10
9
11
class ReferredType <T extends Declaration > extends Type {
10
12
@override
@@ -24,27 +26,76 @@ class ReferredType<T extends Declaration> extends Type {
24
26
25
27
@override
26
28
Reference emit ([TypeOptions ? options]) {
27
- // TODO: implement emit
28
- throw UnimplementedError ();
29
+ // TODO: Support referred types imported from URL
30
+ return TypeReference ((t) => t
31
+ ..symbol = declaration.name
32
+ ..types.addAll (typeParams.map ((t) => t.emit (options)))
33
+ ..isNullable = options? .nullable);
29
34
}
30
35
}
31
36
32
37
// TODO(https://github.com/dart-lang/web/issues/385): Implement Support for UnionType (including implementing `emit`)
33
38
class UnionType extends Type {
34
- List <Type > types;
39
+ final List <Type > types;
35
40
36
41
UnionType ({required this .types});
37
42
38
43
@override
39
- ID get id => ID (type: 'type' , name: types.map ((t) => t.id).join ('|' ));
44
+ ID get id => ID (type: 'type' , name: types.map ((t) => t.id.name).join ('|' ));
45
+
46
+ @override
47
+ String ? get name => null ;
40
48
41
49
@override
42
50
Reference emit ([TypeOptions ? options]) {
43
51
throw UnimplementedError ('TODO: Implement UnionType.emit' );
44
52
}
53
+ }
54
+
55
+ // TODO: Handle naming anonymous declarations
56
+ // TODO: Extract having a declaration associated with a type to its own type
57
+ // (e.g DeclarationAssociatedType)
58
+ class HomogenousEnumType <T extends LiteralType , D extends Declaration >
59
+ extends UnionType {
60
+ final List <T > _types;
45
61
46
62
@override
47
- String ? get name => null ;
63
+ List <T > get types => _types;
64
+
65
+ final Type baseType;
66
+
67
+ final bool isNullable;
68
+
69
+ String declarationName;
70
+
71
+ HomogenousEnumType (
72
+ {required List <T > types, this .isNullable = false , required String name})
73
+ : declarationName = name,
74
+ _types = types,
75
+ baseType = types.first.baseType,
76
+ super (types: types);
77
+
78
+ EnumDeclaration get declaration => EnumDeclaration (
79
+ name: declarationName,
80
+ dartName: UniqueNamer .makeNonConflicting (declarationName),
81
+ baseType: baseType,
82
+ members: types.map ((t) {
83
+ final name = t.value.toString ();
84
+ return EnumMember (
85
+ name,
86
+ t.value,
87
+ dartName: UniqueNamer .makeNonConflicting (name),
88
+ parent: UniqueNamer .makeNonConflicting (declarationName),
89
+ );
90
+ }).toList (),
91
+ exported: true );
92
+
93
+ @override
94
+ Reference emit ([TypeOptions ? options]) {
95
+ return TypeReference ((t) => t
96
+ ..symbol = declarationName
97
+ ..isNullable = options? .nullable ?? isNullable);
98
+ }
48
99
}
49
100
50
101
/// The base class for a type generic (like 'T')
@@ -58,13 +109,62 @@ class GenericType extends Type {
58
109
59
110
GenericType ({required this .name, this .constraint, this .parent});
60
111
112
+ @override
113
+ ID get id =>
114
+ ID (type: 'generic-type' , name: '$name @${parent ?.id ?? "(anonymous)" }' );
115
+
61
116
@override
62
117
Reference emit ([TypeOptions ? options]) => TypeReference ((t) => t
63
118
..symbol = name
64
119
..bound = constraint? .emit ()
65
120
..isNullable = options? .nullable);
121
+ }
122
+
123
+ /// A type representing a bare literal, such as `null` , a string or number
124
+ class LiteralType extends Type {
125
+ final LiteralKind kind;
126
+
127
+ final Object ? value;
66
128
67
129
@override
68
- ID get id =>
69
- ID (type: 'generic-type' , name: '$name @${parent ?.id ?? "(anonymous)" }' );
130
+ String get name => switch (kind) {
131
+ LiteralKind .$null => 'null' ,
132
+ LiteralKind .int || LiteralKind .double => 'number' ,
133
+ LiteralKind .string => 'string' ,
134
+ LiteralKind .$true => 'true' ,
135
+ LiteralKind .$false => 'false'
136
+ };
137
+
138
+ BuiltinType get baseType {
139
+ final primitive = kind.primitive;
140
+
141
+ return BuiltinType .primitiveType (primitive);
142
+ }
143
+
144
+ LiteralType ({required this .kind, required this .value});
145
+
146
+ @override
147
+ Reference emit ([TypeOptions ? options]) {
148
+ return baseType.emit (options);
149
+ }
150
+
151
+ @override
152
+ ID get id => ID (type: 'type' , name: name);
153
+ }
154
+
155
+ enum LiteralKind {
156
+ $null,
157
+ string,
158
+ double ,
159
+ $true,
160
+ $false,
161
+ int ;
162
+
163
+ PrimitiveType get primitive => switch (this ) {
164
+ LiteralKind .$null => PrimitiveType .undefined,
165
+ LiteralKind .string => PrimitiveType .string,
166
+ LiteralKind .int => PrimitiveType .num ,
167
+ LiteralKind .double => PrimitiveType .double ,
168
+ LiteralKind .$true || LiteralKind .$false => PrimitiveType .boolean
169
+ };
70
170
}
0 commit comments