Skip to content

Commit cbb9e5c

Browse files
committed
support typedef enums marked with @MappableEnum
1 parent ff83878 commit cbb9e5c

8 files changed

Lines changed: 153 additions & 22 deletions

File tree

packages/dart_mappable/test/external_types/external_types_test.dart

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ library;
44
import 'package:dart_mappable/dart_mappable.dart';
55
import 'package:test/test.dart';
66

7+
import 'other/color.dart' as c;
78
import 'other/food.dart' as f;
89
import 'other/models.dart' as m;
910
import 'other/other.dart' as o;
@@ -22,6 +23,9 @@ typedef Animal = o.Animal;
2223
@MappableClass()
2324
typedef Pet = o.Pet;
2425

26+
@MappableEnum()
27+
typedef Color = c.Color;
28+
2529
@MappableClass()
2630
class Person with PersonMappable {
2731
final String firstName;
@@ -36,10 +40,11 @@ void main() {
3640
expect(Cake('Lemon').toMap(), equals({'type': 'Lemon'}));
3741
expect(Person('Anna').toMap(), equals({'first_name': 'Anna'}));
3842
expect(
39-
Pet(Person2('Clara'), 'Buddy').toMap(),
43+
Pet(Person2('Clara'), 'Buddy', Color.Black).toMap(),
4044
equals({
4145
'owner': {'first_name': 'Clara'},
42-
'color': 'Buddy',
46+
'name': 'Buddy',
47+
'color': 'Black',
4348
'type': 'Pet',
4449
}),
4550
);
@@ -49,9 +54,10 @@ void main() {
4954
AnimalMapper.fromMap({
5055
'type': 'Pet',
5156
'owner': {'first_name': 'Clara'},
52-
'color': 'Buddy',
57+
'name': 'Buddy',
58+
'color': 'White',
5359
}),
54-
Pet(Person2('Clara'), 'Buddy'),
60+
Pet(Person2('Clara'), 'Buddy', Color.White),
5561
),
5662
isTrue,
5763
);

packages/dart_mappable/test/external_types/external_types_test.mapper.dart

Lines changed: 71 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
enum Color {
2+
Black, Red, White
3+
}
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
import 'color.dart';
12
import 'models.dart';
23

34
abstract class Animal {
4-
final String color;
5+
final String name;
6+
final Color color;
57

6-
const Animal(this.color);
8+
const Animal(this.name, this.color);
79
}
810

911
class Pet extends Animal {
1012
final Person owner;
1113

12-
const Pet(this.owner, super.color);
14+
const Pet(this.owner, super.name, super.color);
1315
}

packages/dart_mappable_builder/lib/src/elements/class/alias_class_mapper_element.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import '../constructor/constructor_mapper_element.dart';
77
import '../mapper_element.dart';
88
import 'target_class_mapper_element.dart';
99

10-
/// Element interface for all annotated type aliases.
10+
/// Element interface for all annotated class type aliases.
1111
class AliasClassMapperElement extends TargetClassMapperElement {
1212
AliasClassMapperElement._(
1313
super.parent,
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import 'package:analyzer/dart/element/element.dart';
2+
import 'package:dart_mappable/dart_mappable.dart';
3+
4+
import '../../builder_options.dart';
5+
import '../../mapper_group.dart';
6+
import '../mapper_element.dart';
7+
import 'target_enum_mapper_element.dart';
8+
9+
/// Element interface for all annotated enum type aliases.
10+
class AliasEnumMapperElement extends TargetEnumMapperElement {
11+
AliasEnumMapperElement._(
12+
super.parent,
13+
this.alias,
14+
super.element,
15+
super.options,
16+
super.annotation,
17+
super.valueNodes,
18+
);
19+
20+
final TypeAliasElement alias;
21+
22+
static Future<AliasEnumMapperElement> from(
23+
MapperElementGroup parent,
24+
TypeAliasElement alias,
25+
MappableOptions options,
26+
) async {
27+
var element = alias.aliasedType.element as EnumElement;
28+
29+
var annotation = await MapperAnnotation.from<MappableEnum>(alias);
30+
var valueNodes = await TargetEnumMapperElement.getValues(element);
31+
32+
return AliasEnumMapperElement._(
33+
parent,
34+
alias,
35+
element,
36+
options,
37+
annotation,
38+
valueNodes,
39+
);
40+
}
41+
42+
@override
43+
late final String uniqueClassName = alias.name ?? '';
44+
}

packages/dart_mappable_builder/lib/src/elements/enum/target_enum_mapper_element.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import '../mapper_element.dart';
1010
import 'enum_mapper_element.dart';
1111

1212
class TargetEnumMapperElement extends EnumMapperElement {
13-
TargetEnumMapperElement._(
13+
TargetEnumMapperElement(
1414
super.parent,
1515
super.element,
1616
super.options,
@@ -24,9 +24,9 @@ class TargetEnumMapperElement extends EnumMapperElement {
2424
MappableOptions options,
2525
) async {
2626
var annotation = await MapperAnnotation.from<MappableEnum>(element);
27-
var valueNodes = await _getValues(element);
27+
var valueNodes = await getValues(element);
2828

29-
return TargetEnumMapperElement._(
29+
return TargetEnumMapperElement(
3030
parent,
3131
element,
3232
options,
@@ -73,7 +73,7 @@ class TargetEnumMapperElement extends EnumMapperElement {
7373
}
7474
}).toList();
7575

76-
static Future<List<(FieldElement, AstNode?)>> _getValues(
76+
static Future<List<(FieldElement, AstNode?)>> getValues(
7777
EnumElement element,
7878
) async {
7979
var fields = element.fields.where((f) => f.isEnumConstant).toList();

packages/dart_mappable_builder/lib/src/mapper_group.dart

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'elements/class/class_mapper_element.dart';
1212
import 'elements/class/dependent_class_mapper_element.dart';
1313
import 'elements/class/factory_constructor_mapper_element.dart';
1414
import 'elements/class/target_class_mapper_element.dart';
15+
import 'elements/enum/alias_enum_mapper_element.dart';
1516
import 'elements/enum/dependent_enum_mapper_element.dart';
1617
import 'elements/enum/target_enum_mapper_element.dart';
1718
import 'elements/mapper_element.dart';
@@ -125,6 +126,15 @@ class MapperElementGroup {
125126
await DependentRecordMapperElement.from(this, e, options),
126127
);
127128
}
129+
} else {
130+
print('${enumChecker.hasAnnotationOf(e)}, ${e.aliasedType.toString()}, ${e.aliasedType.element.toString()}');
131+
if (enumChecker.hasAnnotationOf(e) && e.aliasedType.element is EnumElement) {
132+
if (e.library == library) {
133+
return await _addMapper(
134+
await AliasEnumMapperElement.from(this, e, options),
135+
);
136+
}
137+
}
128138
}
129139
}
130140
return null;
@@ -410,7 +420,11 @@ class MapperElementGroup {
410420
((e.aliasedType.element is ClassElement &&
411421
classChecker.hasAnnotationOf(e)) ||
412422
(e.aliasedType is RecordType &&
413-
recordChecker.hasAnnotationOf(e)))));
423+
recordChecker.hasAnnotationOf(e)) ||
424+
(e.aliasedType is EnumElement && enumChecker.hasAnnotationOf(e))
425+
)
426+
)
427+
);
414428
}
415429

416430
if (scope == InitializerScope.package ||

0 commit comments

Comments
 (0)