Skip to content

Commit

Permalink
enable reusing annotation constants
Browse files Browse the repository at this point in the history
  • Loading branch information
schultek committed Oct 19, 2024
1 parent 946f2db commit f1f5e96
Show file tree
Hide file tree
Showing 10 changed files with 330 additions and 36 deletions.
50 changes: 50 additions & 0 deletions packages/dart_mappable/test/custom_mapper/annotation_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'package:dart_mappable/dart_mappable.dart';
import 'package:test/test.dart';

import 'custom_mapper_test.dart';

part 'annotation_test.mapper.dart';

const mappable = MappableClass(
uniqueId: 'ABC',
ignoreNull: true,
includeCustomMappers: [PrivateClassMapper()],
);

@mappable
class PrivateContainer with PrivateContainerMappable {
PrivateContainer(this.value);

final MyPrivateClass value;
}

const mappable2 = mappable;

@mappable2
class PrivateContainer2 with PrivateContainer2Mappable {
PrivateContainer2(this.value);

final MyPrivateClass value;
}

void main() {
group('Custom Annotation', () {
tearDown(() {
MapperContainer.globals.unuse<MyPrivateClass>();
});

test('from constant', () {
expect(
PrivateContainer(MyPrivateClass('abc')).toMap(),
equals({'value': 'abc'}),
);
});

test('from nested constant', () {
expect(
PrivateContainer2(MyPrivateClass('abc')).toMap(),
equals({'value': 'abc'}),
);
});
});
}
228 changes: 228 additions & 0 deletions packages/dart_mappable/test/custom_mapper/annotation_test.mapper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter

part of 'annotation_test.dart';

class PrivateContainerMapper extends ClassMapperBase<PrivateContainer> {
PrivateContainerMapper._();

static PrivateContainerMapper? _instance;
static PrivateContainerMapper ensureInitialized() {
if (_instance == null) {
MapperContainer.globals.use(_instance = PrivateContainerMapper._());
MapperContainer.globals.useAll([PrivateClassMapper()]);
}
return _instance!;
}

@override
final String id = 'ABC';

static MyPrivateClass _$value(PrivateContainer v) => v.value;
static const Field<PrivateContainer, MyPrivateClass> _f$value =
Field('value', _$value);

@override
final MappableFields<PrivateContainer> fields = const {
#value: _f$value,
};
@override
final bool ignoreNull = true;

static PrivateContainer _instantiate(DecodingData data) {
return PrivateContainer(data.dec(_f$value));
}

@override
final Function instantiate = _instantiate;

static PrivateContainer fromMap(Map<String, dynamic> map) {
return ensureInitialized().decodeMap<PrivateContainer>(map);
}

static PrivateContainer fromJson(String json) {
return ensureInitialized().decodeJson<PrivateContainer>(json);
}
}

mixin PrivateContainerMappable {
String toJson() {
return PrivateContainerMapper.ensureInitialized()
.encodeJson<PrivateContainer>(this as PrivateContainer);
}

Map<String, dynamic> toMap() {
return PrivateContainerMapper.ensureInitialized()
.encodeMap<PrivateContainer>(this as PrivateContainer);
}

PrivateContainerCopyWith<PrivateContainer, PrivateContainer, PrivateContainer>
get copyWith => _PrivateContainerCopyWithImpl(
this as PrivateContainer, $identity, $identity);
@override
String toString() {
return PrivateContainerMapper.ensureInitialized()
.stringifyValue(this as PrivateContainer);
}

@override
bool operator ==(Object other) {
return PrivateContainerMapper.ensureInitialized()
.equalsValue(this as PrivateContainer, other);
}

@override
int get hashCode {
return PrivateContainerMapper.ensureInitialized()
.hashValue(this as PrivateContainer);
}
}

extension PrivateContainerValueCopy<$R, $Out>
on ObjectCopyWith<$R, PrivateContainer, $Out> {
PrivateContainerCopyWith<$R, PrivateContainer, $Out>
get $asPrivateContainer =>
$base.as((v, t, t2) => _PrivateContainerCopyWithImpl(v, t, t2));
}

abstract class PrivateContainerCopyWith<$R, $In extends PrivateContainer, $Out>
implements ClassCopyWith<$R, $In, $Out> {
$R call({MyPrivateClass? value});
PrivateContainerCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(
Then<$Out2, $R2> t);
}

class _PrivateContainerCopyWithImpl<$R, $Out>
extends ClassCopyWithBase<$R, PrivateContainer, $Out>
implements PrivateContainerCopyWith<$R, PrivateContainer, $Out> {
_PrivateContainerCopyWithImpl(super.value, super.then, super.then2);

@override
late final ClassMapperBase<PrivateContainer> $mapper =
PrivateContainerMapper.ensureInitialized();
@override
$R call({MyPrivateClass? value}) =>
$apply(FieldCopyWithData({if (value != null) #value: value}));
@override
PrivateContainer $make(CopyWithData data) =>
PrivateContainer(data.get(#value, or: $value.value));

@override
PrivateContainerCopyWith<$R2, PrivateContainer, $Out2> $chain<$R2, $Out2>(
Then<$Out2, $R2> t) =>
_PrivateContainerCopyWithImpl($value, $cast, t);
}

class PrivateContainer2Mapper extends ClassMapperBase<PrivateContainer2> {
PrivateContainer2Mapper._();

static PrivateContainer2Mapper? _instance;
static PrivateContainer2Mapper ensureInitialized() {
if (_instance == null) {
MapperContainer.globals.use(_instance = PrivateContainer2Mapper._());
MapperContainer.globals.useAll([PrivateClassMapper()]);
}
return _instance!;
}

@override
final String id = 'ABC';

static MyPrivateClass _$value(PrivateContainer2 v) => v.value;
static const Field<PrivateContainer2, MyPrivateClass> _f$value =
Field('value', _$value);

@override
final MappableFields<PrivateContainer2> fields = const {
#value: _f$value,
};
@override
final bool ignoreNull = true;

static PrivateContainer2 _instantiate(DecodingData data) {
return PrivateContainer2(data.dec(_f$value));
}

@override
final Function instantiate = _instantiate;

static PrivateContainer2 fromMap(Map<String, dynamic> map) {
return ensureInitialized().decodeMap<PrivateContainer2>(map);
}

static PrivateContainer2 fromJson(String json) {
return ensureInitialized().decodeJson<PrivateContainer2>(json);
}
}

mixin PrivateContainer2Mappable {
String toJson() {
return PrivateContainer2Mapper.ensureInitialized()
.encodeJson<PrivateContainer2>(this as PrivateContainer2);
}

Map<String, dynamic> toMap() {
return PrivateContainer2Mapper.ensureInitialized()
.encodeMap<PrivateContainer2>(this as PrivateContainer2);
}

PrivateContainer2CopyWith<PrivateContainer2, PrivateContainer2,
PrivateContainer2>
get copyWith => _PrivateContainer2CopyWithImpl(
this as PrivateContainer2, $identity, $identity);
@override
String toString() {
return PrivateContainer2Mapper.ensureInitialized()
.stringifyValue(this as PrivateContainer2);
}

@override
bool operator ==(Object other) {
return PrivateContainer2Mapper.ensureInitialized()
.equalsValue(this as PrivateContainer2, other);
}

@override
int get hashCode {
return PrivateContainer2Mapper.ensureInitialized()
.hashValue(this as PrivateContainer2);
}
}

extension PrivateContainer2ValueCopy<$R, $Out>
on ObjectCopyWith<$R, PrivateContainer2, $Out> {
PrivateContainer2CopyWith<$R, PrivateContainer2, $Out>
get $asPrivateContainer2 =>
$base.as((v, t, t2) => _PrivateContainer2CopyWithImpl(v, t, t2));
}

abstract class PrivateContainer2CopyWith<$R, $In extends PrivateContainer2,
$Out> implements ClassCopyWith<$R, $In, $Out> {
$R call({MyPrivateClass? value});
PrivateContainer2CopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(
Then<$Out2, $R2> t);
}

class _PrivateContainer2CopyWithImpl<$R, $Out>
extends ClassCopyWithBase<$R, PrivateContainer2, $Out>
implements PrivateContainer2CopyWith<$R, PrivateContainer2, $Out> {
_PrivateContainer2CopyWithImpl(super.value, super.then, super.then2);

@override
late final ClassMapperBase<PrivateContainer2> $mapper =
PrivateContainer2Mapper.ensureInitialized();
@override
$R call({MyPrivateClass? value}) =>
$apply(FieldCopyWithData({if (value != null) #value: value}));
@override
PrivateContainer2 $make(CopyWithData data) =>
PrivateContainer2(data.get(#value, or: $value.value));

@override
PrivateContainer2CopyWith<$R2, PrivateContainer2, $Out2> $chain<$R2, $Out2>(
Then<$Out2, $R2> t) =>
_PrivateContainer2CopyWithImpl($value, $cast, t);
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ void initializeMappers() {
p7.VMapper.ensureInitialized();
p7.WMapper.ensureInitialized();
p8.PrivateContainerMapper.ensureInitialized();
p8.PrivateContainer2Mapper.ensureInitialized();
p9.TestObjMapper.ensureInitialized();
p10.ClassAMapper.ensureInitialized();
p10.EnumAMapper.ensureInitialized();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ abstract class ClassMapperElement extends InterfaceMapperElement<ClassElement>
late final String? hookForClass = () {
var hook = annotation.value?.read('hook');
if (hook != null && !hook.isNull) {
var node = annotation.annotation?.getPropertyNode('hook');
var node = annotation.getPropertyNode('hook');
if (node != null) {
return node.toSource();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ mixin InheritedElementsMixin on MapperElement<ClassElement> {
superElement?.discriminatorKey;

late String? discriminatorValueCode =
annotation.annotation?.getPropertyNode('discriminatorValue')?.toSource();
annotation.getPropertyNode('discriminatorValue')?.toSource();

List<ClassElement> getSubClasses() {
return annotation.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'package:dart_mappable/dart_mappable.dart';

import '../../builder_options.dart';
import '../../mapper_group.dart';
import '../../utils.dart';
import '../constructor/constructor_mapper_element.dart';
import '../mapper_element.dart';
import 'class_mapper_element.dart';
Expand All @@ -27,9 +26,8 @@ class TargetClassMapperElement extends ClassMapperElement

late final String prefixedDecodingClassName = prefixedClassName;

late final String? customMappers = annotation.annotation
?.getPropertyNode('includeCustomMappers')
?.toSource();
late final String? customMappers =
annotation.getPropertyNode('includeCustomMappers')?.toSource();

late final List<String> customTypes = () {
var types = <String>[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,24 @@ import 'field/mapper_field_element.dart';
class MapperAnnotation {
const MapperAnnotation.empty(this.element)
: node = null,
annotation = null,
arguments = null,
value = null;
const MapperAnnotation(this.element, this.node, this.annotation, this.value);
const MapperAnnotation(this.element, this.node, this.arguments, this.value);

final Element element;
final AstNode? node;
final Annotation? annotation;
final ArgumentList? arguments;
final DartObject? value;

static Future<MapperAnnotation> from<T>(Element element) async {
var node = await element.getResolvedNode();
var annotation = getAnnotation(node, T);
var arguments = await getAnnotationArguments(node, T);
var value = TypeChecker.fromRuntime(T).firstAnnotationOf(element);
return MapperAnnotation(element, node, annotation, value);
return MapperAnnotation(element, node, arguments, value);
}

AstNode? getPropertyNode(dynamic /* String | int */ property) {
return arguments?.getArgument(property);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class RecordMapperParamElement extends MapperParamElement {

@override
Future<String?> getHook() async {
var node = getAnnotationProperty(param, MappableField, 'hook');
var node = await getAnnotationProperty(param, MappableField, 'hook');
return node?.toSource();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import 'record_mapper_element.dart';

class RecordMapperAnnotation extends MapperAnnotation {
RecordMapperAnnotation(super.element, RecordTypeAnnotation super.node,
super.annotation, super.value);
super.arguments, super.value);

@override
RecordTypeAnnotation get node => super.node as RecordTypeAnnotation;
Expand All @@ -25,11 +25,11 @@ class RecordMapperAnnotation extends MapperAnnotation {
.where((d) => d.name.lexeme == element.name)
.first;

var annotation = getAnnotation(node, MappableRecord);
var arguments = await getAnnotationArguments(node, MappableRecord);
var value =
TypeChecker.fromRuntime(MappableRecord).firstAnnotationOf(element);
return RecordMapperAnnotation(
element, node.type as RecordTypeAnnotation, annotation, value);
element, node.type as RecordTypeAnnotation, arguments, value);
}
}

Expand Down
Loading

0 comments on commit f1f5e96

Please sign in to comment.