classDefinitionToSpec function
Spec
classDefinitionToSpec(
- ClassDefinition definition,
- Iterable<
FragmentClassDefinition> fragments, - Iterable<
ClassDefinition> classes
Generates a Spec
of a single class definition.
Implementation
Spec classDefinitionToSpec(
ClassDefinition definition,
Iterable<FragmentClassDefinition> fragments,
Iterable<ClassDefinition> classes) {
final fromJson = definition.factoryPossibilities.isNotEmpty
? Constructor(
(b) => b
..factory = true
..name = 'fromJson'
..requiredParameters.add(Parameter(
(p) => p
..type = refer('Map<String, dynamic>')
..name = 'json',
))
..body = Code(_fromJsonBody(definition)),
)
: Constructor(
(b) => b
..factory = true
..name = 'fromJson'
..lambda = true
..requiredParameters.add(Parameter(
(p) => p
..type = refer('Map<String, dynamic>')
..name = 'json',
))
..body = Code('_\$${definition.name.namePrintable}FromJson(json)'),
);
final toJson = definition.factoryPossibilities.isNotEmpty
? Method(
(m) => m
..name = 'toJson'
..annotations.add(CodeExpression(Code('override')))
..returns = refer('Map<String, dynamic>')
..body = Code(_toJsonBody(definition)),
)
: Method(
(m) => m
..name = 'toJson'
..lambda = true
..annotations.add(CodeExpression(Code('override')))
..returns = refer('Map<String, dynamic>')
..body = Code('_\$${definition.name.namePrintable}ToJson(this)'),
);
final props = definition.mixins
.map((i) {
return fragments
.firstWhere((f) {
return f.name == i;
}, orElse: () {
throw MissingFragmentException(
i.namePrintable, definition.name.namePrintable);
})
.properties
.map((p) => p.name.namePrintable);
})
.expand((i) => i)
.followedBy(definition.properties.map((p) => p.name.namePrintable));
final extendedClass =
classes.firstWhereOrNull((e) => e.name == definition.extension);
return Class(
(b) => b
..annotations
.add(CodeExpression(Code('JsonSerializable(explicitToJson: true)')))
..name = definition.name.namePrintable
..mixins.add(refer('EquatableMixin'))
..mixins.addAll(definition.mixins.map((i) => refer(i.namePrintable)))
..methods.add(_propsMethod(props))
..extend = definition.extension != null
? refer(definition.extension!.namePrintable)
: refer('JsonSerializable')
..implements.addAll(definition.implementations.map((i) => refer(i)))
..constructors.add(Constructor((b) {
if (definition.isInput) {
b.optionalParameters.addAll(definition.properties
.where(
(property) => !property.isOverride && !property.isResolveType)
.map(
(property) => Parameter(
(p) {
p
..name = property.name.namePrintable
..named = true
..toThis = true
..required = property.type.isNonNull;
},
),
));
}
}))
..constructors.add(fromJson)
..methods.add(toJson)
..fields.addAll(definition.properties.map((p) {
if (extendedClass != null &&
extendedClass.properties.any((e) => e == p)) {
// if class has the same prop as in extension
p.annotations.add('override');
}
final field = Field((f) {
f
..name = p.name.namePrintable
// TODO: remove this workaround when code_builder includes late field modifier:
// https://github.com/dart-lang/code_builder/pull/310
..type = refer(
'${p.type.isNonNull ? 'late ' : ''} ${p.type.namePrintable}')
..annotations.addAll(
p.annotations.map((e) => CodeExpression(Code(e))),
);
if (p.type.isNonNull) {
// TODO: apply this fix when code_builder includes late field modifier:
// https://github.com/dart-lang/code_builder/pull/310
// f.modifier = FieldModifier.late$;
}
});
return field;
})),
);
}