diff --git a/.idea/runConfigurations/tests_in_enum_test_dart.xml b/.idea/runConfigurations/tests_in_enum_test_dart.xml
new file mode 100644
index 00000000..9a4a3357
--- /dev/null
+++ b/.idea/runConfigurations/tests_in_enum_test_dart.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index de5d50ea..65405b21 100644
--- a/README.md
+++ b/README.md
@@ -61,9 +61,20 @@ part 'book.g.dart';
@serializable
abstract class _Book extends Model {
String get author;
+
String get title;
+
String get description;
+
int get pageCount;
+
+ BookType get type;
+}
+
+/// It even supports enums!
+enum BookType {
+ fiction,
+ nonFiction
}
```
diff --git a/angel_serialize_generator/CHANGELOG.md b/angel_serialize_generator/CHANGELOG.md
index dd455c0f..6f2f8bd8 100644
--- a/angel_serialize_generator/CHANGELOG.md
+++ b/angel_serialize_generator/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 2.0.9
+* Now supports de/serialization of `enum` types.
+* Generate `const` constructors when possible.
+* Remove `whereType`, perform manual coercion.
+
# 2.0.8
* Generate a `fromMap` with typecasting, for Dart 2's sake.
diff --git a/angel_serialize_generator/build.yaml b/angel_serialize_generator/build.yaml
index 842854c9..85a0a683 100644
--- a/angel_serialize_generator/build.yaml
+++ b/angel_serialize_generator/build.yaml
@@ -23,6 +23,7 @@ targets:
_book:
sources:
- "test/models/book.dart"
+ - "test/models/with_enum.dart"
_typescript_definition:
sources:
- "lib/*.dart"
diff --git a/angel_serialize_generator/lib/angel_serialize_generator.dart b/angel_serialize_generator/lib/angel_serialize_generator.dart
index 486fd071..c361f677 100644
--- a/angel_serialize_generator/lib/angel_serialize_generator.dart
+++ b/angel_serialize_generator/lib/angel_serialize_generator.dart
@@ -3,6 +3,7 @@ library angel_serialize_generator;
import 'dart:async';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:angel_model/angel_model.dart';
import 'package:angel_serialize/angel_serialize.dart';
import 'package:build/build.dart';
import 'package:code_buffer/code_buffer.dart';
@@ -66,6 +67,14 @@ bool isListOrMapType(DartType t) {
const TypeChecker.fromRuntime(Map).isAssignableFromType(t);
}
+bool isEnumType(DartType t) {
+ if (t is InterfaceType) {
+ return t.element.isEnum;
+ }
+
+ return false;
+}
+
/// Determines if a [DartType] is a `List` with the first type argument being a `Model`.
bool isListModelType(InterfaceType t) {
return const TypeChecker.fromRuntime(List).isAssignableFromType(t) &&
@@ -80,6 +89,8 @@ bool isMapToModelType(InterfaceType t) {
isModelClass(t.typeArguments[1]);
}
+bool isAssignableToModel(DartType type) => const TypeChecker.fromRuntime(Model).isAssignableFromType(type);
+
/// Compute a [String] representation of a [type].
String typeToString(DartType type) {
if (type is InterfaceType) {
diff --git a/angel_serialize_generator/lib/model.dart b/angel_serialize_generator/lib/model.dart
index 90a81513..1a767c1b 100644
--- a/angel_serialize_generator/lib/model.dart
+++ b/angel_serialize_generator/lib/model.dart
@@ -26,9 +26,13 @@ class JsonModelGenerator extends GeneratorForAnnotation {
void generateClass(
BuildContext ctx, LibraryBuilder file, ConstantReader annotation) {
file.body.add(new Class((clazz) {
- clazz
- ..name = ctx.modelClassNameRecase.pascalCase
- ..extend = new Reference(ctx.originalClassName);
+ clazz..name = ctx.modelClassNameRecase.pascalCase;
+
+ if (shouldBeConstant(ctx)) {
+ clazz.implements.add(new Reference(ctx.originalClassName));
+ } else {
+ clazz.extend = new Reference(ctx.originalClassName);
+ }
//if (ctx.importsPackageMeta)
// clazz.annotations.add(new CodeExpression(new Code('immutable')));
@@ -61,11 +65,19 @@ class JsonModelGenerator extends GeneratorForAnnotation {
}));
}
+ bool shouldBeConstant(BuildContext ctx) {
+ // Check if all fields are without a getter
+ return !isAssignableToModel(ctx.clazz.type) &&
+ ctx.clazz.fields.every((f) => f.getter == null || f.setter == null);
+ }
+
/// Generate a constructor with named parameters.
void generateConstructor(
BuildContext ctx, ClassBuilder clazz, LibraryBuilder file) {
clazz.constructors.add(new Constructor((constructor) {
// Add all `super` params
+ constructor.constant = ctx.clazz.unnamedConstructor?.isConst == true ||
+ shouldBeConstant(ctx);
for (var param in ctx.constructorParameters) {
constructor.requiredParameters.add(new Parameter((b) => b
@@ -156,7 +168,7 @@ class JsonModelGenerator extends GeneratorForAnnotation {
}
static String generateEquality(DartType type, [bool nullable = false]) {
- //if (type is! InterfaceType) return 'const DefaultEquality()';
+//if (type is! InterfaceType) return 'const DefaultEquality()';
var it = type as InterfaceType;
if (const TypeChecker.fromRuntime(List).isAssignableFromType(type)) {
if (it.typeParameters.length == 1) {
diff --git a/angel_serialize_generator/lib/serialize.dart b/angel_serialize_generator/lib/serialize.dart
index cbd1b229..b544acd7 100644
--- a/angel_serialize_generator/lib/serialize.dart
+++ b/angel_serialize_generator/lib/serialize.dart
@@ -112,6 +112,12 @@ class SerializerGenerator extends GeneratorForAnnotation {
return map..[key] = ${rc.pascalCase}Serializer.toMap(model.${field
.name}[key]);
})''';
+ } else if (t.element.isEnum) {
+ serializedRepresentation = '''
+ model.${field.name} == null ?
+ null
+ : ${t.name}.values.indexOf(model.${field.name})
+ ''';
}
}
@@ -193,19 +199,31 @@ class SerializerGenerator extends GeneratorForAnnotation {
if (isListModelType(t)) {
var rc = new ReCase(t.typeArguments[0].name);
deserializedRepresentation = "map['$alias'] is Iterable"
- " ? new List.unmodifiable((map['$alias'] as Iterable).whereType