generate method
Implementation
@override
String generate(List<ClassMember> members) {
var serialize = '';
for (var member in members) {
if (!(member is FieldDeclaration)) continue;
final fieldType = member.fields.type;
final namedType = fieldType is NamedType ? fieldType : null;
final typeArgs = namedType?.typeArguments?.arguments;
final isNullable = member.fields.type?.question != null;
final dot = isNullable ? '?.' : '.';
final type = member.fields.type
.toString()
.replaceAll('\$', '')
.replaceAll('?', '');
final name = member.fields.variables.first.name.lexeme;
if (primitives.contains(type)) {
serialize += "'$name': $name,";
} else if (type == 'Type') {
serialize += "'$name': 'Type<$name>',";
} else if (type == 'double') {
serialize += "'$name': $name,";
} else if (type == 'Decimal') {
serialize += "'$name': $name${dot}toDouble(),";
} else if (enums.contains(type)) {
serialize += "'$name': $name${dot}value,";
} else if (type.contains('Map<')) {
final keyType = _cleanType(typeArgs?.elementAtOrNull(0));
final originalValueType = typeArgs?.elementAtOrNull(1);
final valueType = _cleanType(originalValueType);
final isValueNullable = originalValueType?.question != null;
final valueDot = isValueNullable ? '?.' : '.';
// Determine if key needs string conversion for JSON serialization
final isKeyString = keyType == 'String';
final needsKeyConversion =
!isKeyString && ['num', 'bool', 'int', 'double'].contains(keyType);
final keyExpr = needsKeyConversion ? 'k.toString()' : 'k';
// Check if value is a generic type parameter from class declaration
final isGenericValueType = typeParams.contains(valueType);
var valueExpr = isGenericValueType
? '(v as dynamic)?.serialize()'
: 'v${valueDot}serialize()';
if (primitives.contains(valueType)) {
valueExpr = 'v';
} else if (enums.contains(valueType)) {
valueExpr = 'v${valueDot}value';
} else if (valueType.startsWith('List<')) {
final valueNamedType =
originalValueType is NamedType ? originalValueType : null;
final listValueType =
valueNamedType?.typeArguments?.arguments.elementAtOrNull(0);
final listPrimitive = _cleanType(listValueType);
final listItemDot = listValueType?.question == null ? '.' : '?.';
final isGenericListType = typeParams.contains(listPrimitive);
if (primitives.contains(listPrimitive)) {
valueExpr = 'v';
} else if (enums.contains(listPrimitive)) {
valueExpr = 'v${valueDot}map((i) => i${listItemDot}value).toList()';
} else if (isGenericListType) {
valueExpr =
'v${valueDot}map((i) => (i as dynamic)?.serialize()).toList()';
} else {
valueExpr =
'v${valueDot}map((i) => i${listItemDot}serialize()).toList()';
}
}
if (!needsKeyConversion && valueExpr == 'v') {
serialize += "'$name': $name,";
} else {
serialize +=
"'$name': $name${dot}map<String, dynamic>((k, v) => MapEntry($keyExpr, $valueExpr)),";
}
} else if (type == 'Map') {
serialize += "'$name': $name,";
} else if (type.contains('List<')) {
final dotMap = isNullable ? '?.map' : '.map';
final listValueType = typeArgs?.elementAtOrNull(0);
final listPrimitive = _cleanType(listValueType);
final listItemDot = listValueType?.question == null ? '.' : '?.';
// Check if it's a generic type parameter from class declaration
final isGenericType = typeParams.contains(listPrimitive);
if (primitives.contains(listPrimitive)) {
serialize += "'$name': $name,";
} else if (enums.contains(listPrimitive)) {
serialize +=
"'$name': $name$dotMap((i) => i${listItemDot}value).toList(),";
} else if (isGenericType) {
// For generic types, use dynamic with null-safe call since T might not have serialize()
serialize +=
"'$name': $name$dotMap((i) => (i as dynamic)?.serialize()).toList(),";
} else {
serialize +=
"'$name': $name$dotMap((i) => i${listItemDot}serialize()).toList(),";
}
} else {
if (isNullable) {
serialize += "'$name': $name?.serialize(),";
} else {
serialize += "'$name': $name.serialize(),";
}
}
}
return 'Map<String, dynamic> serialize() => {$serialize};';
}