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(const CodeExpression(Code('override')))
..returns = refer('Map<String, dynamic>')
..body = Code(_toJsonBody(definition)),
)
: Method(
(m) => m
..name = 'toJson'
..lambda = true
..annotations.add(const 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(
const CodeExpression(Code('JsonSerializable(explicitToJson: true)')),
)
..name = definition.name.namePrintable
..mixins.addAll([
refer('EquatableMixin'),
...definition.mixins.map((i) => refer(i.namePrintable)),
])
..methods.addAll([_propsMethod(props)])
..extend = definition.extension != null
? refer(definition.extension!.namePrintable)
: refer('JsonSerializable')
..implements.addAll(definition.implementations.map(refer))
..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;
}),
),
);
}
}),
)
// Always add fromJson constructor (either delegating or traditional)
..constructors.add(fromJson)
// Only add toJson method when not using GraphQLDataClass
..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
..late = p.type.isNonNull
..type = refer(p.type.namePrintable)
..annotations.addAll(
p.annotations.map((e) => CodeExpression(Code(e))),
);
});
return field;
}),
),
);
}