in working/macros/example/data_class.dart [40:114]
Future<void> buildDeclarationsForClass(
ClassDeclaration clazz, ClassMemberDeclarationBuilder builder) async {
var constructors = await builder.constructorsOf(clazz);
if (constructors.any((c) => c.identifier.name == '')) {
throw ArgumentError(
'Cannot generate an unnamed constructor because one already exists');
}
var parts = <Object>[clazz.identifier.name, '({'];
// Add all the fields of `declaration` as named parameters.
var fields = await builder.fieldsOf(clazz);
for (var field in fields) {
var requiredKeyword = field.type.isNullable ? '' : 'required ';
parts.addAll(['\n${requiredKeyword}this.', field.identifier.name, ',']);
}
// Add all super constructor parameters as named parameters.
var superclass = (await builder.superclassOf(clazz))!;
MethodDeclaration? superconstructor;
// TODO: Compare against Object identifier once we can get it.
if (superclass.identifier.name != 'Object') {
var superconstructor = (await builder.constructorsOf(superclass))
.firstWhereOrNull((c) => c.identifier.name == '');
if (superconstructor == null) {
throw ArgumentError(
'Super class $superclass of $clazz does not have an unnamed '
'constructor');
}
// We convert positional parameters in the super constructor to named
// parameters in this constructor.
for (var param in superconstructor.positionalParameters) {
var requiredKeyword = param.isRequired ? 'required' : '';
var defaultValue = param.defaultValue == null
? ''
: Code.fromParts([' = ', param.defaultValue!]);
parts.addAll([
'\n$requiredKeyword',
param.type.code,
' ${param.identifier.name},',
defaultValue,
',',
]);
}
for (var param in superconstructor.namedParameters) {
var requiredKeyword = param.isRequired ? '' : 'required ';
var defaultValue = param.defaultValue == null
? ''
: Code.fromParts([' = ', param.defaultValue!]);
parts.addAll([
'\n$requiredKeyword',
param.type.code,
' ${param.identifier.name}',
defaultValue,
',',
]);
}
}
parts.add('\n})');
if (superconstructor != null) {
parts.add(' : super(');
for (var param in superconstructor.positionalParameters) {
parts.add('\n${param.identifier.name},');
}
if (superconstructor.namedParameters.isNotEmpty) {
parts.add('{');
for (var param in superconstructor.namedParameters) {
parts.add('\n${param.identifier.name}: ${param.identifier.name},');
}
parts.add('\n}');
}
parts.add(')');
}
parts.add(';');
builder.declareInClass(DeclarationCode.fromParts(parts));
}