platform/packages/serialize/angel_serialize_generator/lib/context.dart

119 lines
3.8 KiB
Dart
Raw Normal View History

2018-12-31 01:18:44 +00:00
import 'package:analyzer/dart/constant/value.dart';
2017-06-20 22:13:04 +00:00
import 'package:analyzer/dart/element/element.dart';
2019-01-09 19:25:05 +00:00
import 'package:analyzer/dart/element/type.dart';
2021-05-15 14:37:52 +00:00
import 'package:angel3_serialize/angel3_serialize.dart';
2018-02-27 20:03:58 +00:00
import 'package:code_builder/code_builder.dart';
2018-02-27 19:42:06 +00:00
import 'package:recase/recase.dart';
import 'package:source_gen/source_gen.dart';
2017-06-20 22:13:04 +00:00
2018-02-27 19:20:39 +00:00
/// A base context for building serializable classes.
2017-06-20 22:13:04 +00:00
class BuildContext {
2021-05-02 06:02:08 +00:00
ReCase? _modelClassNameRecase;
TypeReference? _modelClassType;
2018-02-27 19:42:06 +00:00
2018-05-15 19:11:12 +00:00
/// A map of fields that are absolutely required, and error messages for when they are absent.
final Map<String, String> requiredFields = {};
2018-02-27 19:20:39 +00:00
/// A map of field names to resolved names from `@Alias()` declarations.
2021-08-08 03:10:35 +00:00
final Map<String, String> aliases = {};
2018-02-27 19:20:39 +00:00
2018-12-31 01:18:44 +00:00
/// A map of field names to their default values.
2021-08-08 03:10:35 +00:00
final Map<String, DartObject> defaults = {};
2018-12-31 01:18:44 +00:00
2019-01-07 00:56:05 +00:00
/// A map of fields to their related information.
2019-01-09 19:25:05 +00:00
final Map<String, SerializableFieldMirror> fieldInfo = {};
2019-01-07 00:56:05 +00:00
2018-02-28 00:36:53 +00:00
/// A map of fields that have been marked as to be excluded from serialization.
2019-01-07 00:56:05 +00:00
// ignore: deprecated_member_use
final Map<String, Exclude> excluded = {};
2018-02-28 00:36:53 +00:00
2018-02-27 19:20:39 +00:00
/// A map of "synthetic" fields, i.e. `id` and `created_at` injected automatically.
2017-06-20 22:13:04 +00:00
final Map<String, bool> shimmed = {};
2018-02-27 19:20:39 +00:00
2021-08-08 03:10:35 +00:00
final bool autoIdAndDateFields;
final bool autoSnakeCaseNames;
2018-02-28 00:50:16 +00:00
2021-05-02 06:02:08 +00:00
final String? originalClassName, sourceFilename;
2018-02-27 19:20:39 +00:00
/// The fields declared on the original class.
2017-06-20 22:13:04 +00:00
final List<FieldElement> fields = [];
2018-02-27 19:20:39 +00:00
2018-05-13 17:23:40 +00:00
final List<ParameterElement> constructorParameters = [];
final ConstantReader annotation;
2018-02-27 19:20:39 +00:00
final InterfaceElement clazz;
2019-01-07 00:56:05 +00:00
/// Any annotations to include in the generated class.
final List<DartObject> includeAnnotations;
2018-02-27 19:20:39 +00:00
/// The name of the field that identifies data of this model type.
2017-06-20 22:13:04 +00:00
String primaryKeyName = 'id';
BuildContext(this.annotation, this.clazz,
2018-02-28 00:50:16 +00:00
{this.originalClassName,
this.sourceFilename,
2021-08-08 03:10:35 +00:00
this.autoSnakeCaseNames = true,
this.autoIdAndDateFields = true,
2019-04-30 15:44:01 +00:00
this.includeAnnotations = const <DartObject>[]});
2017-06-20 22:13:04 +00:00
2018-02-27 19:20:39 +00:00
/// The name of the generated class.
2021-08-08 03:10:35 +00:00
String? get modelClassName => originalClassName?.startsWith('_') == true
? originalClassName?.substring(1)
2017-06-20 22:13:04 +00:00
: originalClassName;
2018-02-27 19:42:06 +00:00
/// A [ReCase] instance reflecting on the [modelClassName].
2021-08-08 03:10:35 +00:00
ReCase get modelClassNameRecase {
if (modelClassName == null) {
throw ArgumentError('Model class cannot be null');
}
_modelClassNameRecase ??= ReCase(modelClassName!);
return _modelClassNameRecase!;
}
2018-02-27 20:03:58 +00:00
TypeReference get modelClassType =>
2019-04-30 15:44:01 +00:00
_modelClassType ??= TypeReference((b) => b.symbol = modelClassName);
2018-02-27 19:42:06 +00:00
2018-02-27 19:20:39 +00:00
/// The [FieldElement] pointing to the primary key.
FieldElement get primaryKeyField =>
fields.firstWhere((f) => f.name == primaryKeyName);
2018-05-15 19:33:57 +00:00
bool get importsPackageMeta {
return clazz.library.imports.any((i) => i.uri == 'package:meta/meta.dart');
}
2018-02-27 19:20:39 +00:00
/// Get the aliased name (if one is defined) for a field.
2021-05-02 06:02:08 +00:00
String? resolveFieldName(String name) =>
2017-06-20 22:13:04 +00:00
aliases.containsKey(name) ? aliases[name] : name;
2019-01-09 19:25:05 +00:00
/// Finds the type that the field [name] should serialize to.
DartType resolveSerializedFieldType(String name) {
return fieldInfo[name]?.serializesTo ??
fields.firstWhere((f) => f.name == name).type;
}
}
class SerializableFieldMirror {
2021-05-02 06:02:08 +00:00
final String? alias;
final DartObject? defaultValue;
final Symbol? serializer, deserializer;
final String? errorMessage;
2021-08-08 03:10:35 +00:00
final bool isNullable;
final bool canDeserialize;
final bool canSerialize;
final bool exclude;
2021-05-02 06:02:08 +00:00
final DartType? serializesTo;
2019-01-09 19:25:05 +00:00
SerializableFieldMirror(
{this.alias,
this.defaultValue,
this.serializer,
this.deserializer,
this.errorMessage,
2021-08-08 03:10:35 +00:00
this.isNullable = false,
this.canDeserialize = true,
this.canSerialize = true,
this.exclude = false,
2019-01-09 19:25:05 +00:00
this.serializesTo});
2017-06-20 22:13:04 +00:00
}