-
Notifications
You must be signed in to change notification settings - Fork 33
[interop] Add Support for Enums #404
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,14 @@ | |
import 'package:code_builder/code_builder.dart'; | ||
import '../interop_gen/namer.dart'; | ||
import 'base.dart'; | ||
import 'builtin.dart'; | ||
import 'declarations.dart'; | ||
|
||
abstract interface class DeclarationAssociatedType { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's wait to add this type until we need it (and at that point decide on naming). It looks like only There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now, the type does not handle naming: naming is done externally when transforming |
||
String get declarationName; | ||
|
||
Declaration get declaration; | ||
} | ||
|
||
class ReferredType<T extends Declaration> extends Type { | ||
@override | ||
|
@@ -24,27 +32,76 @@ class ReferredType<T extends Declaration> extends Type { | |
|
||
@override | ||
Reference emit([TypeOptions? options]) { | ||
// TODO: implement emit | ||
throw UnimplementedError(); | ||
// TODO: Support referred types imported from URL | ||
return TypeReference((t) => t | ||
..symbol = declaration.name | ||
..types.addAll(typeParams.map((t) => t.emit(options))) | ||
..isNullable = options?.nullable); | ||
} | ||
} | ||
|
||
// TODO(https://github.com/dart-lang/web/issues/385): Implement Support for UnionType (including implementing `emit`) | ||
class UnionType extends Type { | ||
List<Type> types; | ||
final List<Type> types; | ||
|
||
UnionType({required this.types}); | ||
|
||
@override | ||
ID get id => ID(type: 'type', name: types.map((t) => t.id).join('|')); | ||
ID get id => ID(type: 'type', name: types.map((t) => t.id.name).join('|')); | ||
|
||
@override | ||
String? get name => null; | ||
|
||
@override | ||
Reference emit([TypeOptions? options]) { | ||
throw UnimplementedError('TODO: Implement UnionType.emit'); | ||
} | ||
} | ||
|
||
// TODO: Handle naming anonymous declarations | ||
class HomogenousUnionType<T extends LiteralType, D extends Declaration> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or maybe |
||
extends UnionType implements DeclarationAssociatedType { | ||
final List<T> _types; | ||
|
||
@override | ||
String? get name => null; | ||
List<T> get types => _types; | ||
|
||
final Type baseType; | ||
|
||
final bool isNullable; | ||
|
||
@override | ||
String declarationName; | ||
|
||
HomogenousUnionType( | ||
{required List<T> types, this.isNullable = false, required String name}) | ||
: declarationName = name, | ||
_types = types, | ||
baseType = types.first.baseType, | ||
super(types: types); | ||
|
||
@override | ||
EnumDeclaration get declaration => EnumDeclaration( | ||
name: declarationName, | ||
dartName: UniqueNamer.makeNonConflicting(declarationName), | ||
baseType: baseType, | ||
members: types.map((t) { | ||
final name = t.value.toString(); | ||
return EnumMember( | ||
name, | ||
t.value, | ||
dartName: UniqueNamer.makeNonConflicting(name), | ||
parent: UniqueNamer.makeNonConflicting(declarationName), | ||
); | ||
}).toList(), | ||
exported: true); | ||
|
||
@override | ||
Reference emit([TypeOptions? options]) { | ||
return TypeReference((t) => t | ||
..symbol = declarationName | ||
..isNullable = options?.nullable ?? isNullable); | ||
} | ||
} | ||
|
||
/// The base class for a type generic (like 'T') | ||
|
@@ -58,13 +115,62 @@ class GenericType extends Type { | |
|
||
GenericType({required this.name, this.constraint, this.parent}); | ||
|
||
@override | ||
ID get id => | ||
ID(type: 'generic-type', name: '$name@${parent?.id ?? "(anonymous)"}'); | ||
|
||
@override | ||
Reference emit([TypeOptions? options]) => TypeReference((t) => t | ||
..symbol = name | ||
..bound = constraint?.emit() | ||
..isNullable = options?.nullable); | ||
} | ||
|
||
/// A type representing a bare literal, such as `null`, a string or number | ||
class LiteralType extends Type { | ||
final LiteralKind kind; | ||
|
||
final Object? value; | ||
|
||
@override | ||
ID get id => | ||
ID(type: 'generic-type', name: '$name@${parent?.id ?? "(anonymous)"}'); | ||
String get name => switch (kind) { | ||
LiteralKind.$null => 'null', | ||
LiteralKind.int || LiteralKind.double => 'number', | ||
LiteralKind.string => 'string', | ||
LiteralKind.$true => 'true', | ||
LiteralKind.$false => 'false' | ||
}; | ||
|
||
BuiltinType get baseType { | ||
final primitive = kind.primitive; | ||
|
||
return BuiltinType.primitiveType(primitive); | ||
} | ||
|
||
LiteralType({required this.kind, required this.value}); | ||
|
||
@override | ||
Reference emit([TypeOptions? options]) { | ||
return baseType.emit(options); | ||
} | ||
|
||
@override | ||
ID get id => ID(type: 'type', name: name); | ||
} | ||
|
||
enum LiteralKind { | ||
$null, | ||
string, | ||
double, | ||
$true, | ||
$false, | ||
int; | ||
|
||
PrimitiveType get primitive => switch (this) { | ||
LiteralKind.$null => PrimitiveType.undefined, | ||
LiteralKind.string => PrimitiveType.string, | ||
LiteralKind.int => PrimitiveType.num, | ||
LiteralKind.double => PrimitiveType.double, | ||
LiteralKind.$true || LiteralKind.$false => PrimitiveType.boolean | ||
}; | ||
} |
Uh oh!
There was an error while loading. Please reload this page.