generateClass function
Implementation
String generateClass(
String className,
Map<String, dynamic> def,
Map<String, dynamic> allDefs,
) {
final props = (def['properties'] as Map?)?.cast<String, dynamic>() ?? {};
final requiredList = (def['required'] is List)
? (def['required'] as List).cast<String>()
: <String>[];
final fields = <FieldSpec>[];
for (final entry in props.entries) {
final jsonKey = entry.key;
final schema = (entry.value as Map).cast<String, dynamic>();
String dartType = 'dynamic';
if (schema[r'$ref'] is String) {
dartType = refToName(schema[r'$ref'] as String);
} else if (schema['type'] is String) {
dartType = typeToDart(schema['type'] as String, schema);
}
final isRequired = requiredList.contains(jsonKey);
final fieldName = sanitizeFieldName(jsonKey);
fields.add(FieldSpec(
fieldName: fieldName,
jsonKey: jsonKey,
type: isRequired ? dartType : '$dartType?',
nullable: !isRequired,
description: schema['description'] as String?,
));
}
final b = StringBuffer();
// Doc
b.writeln('class $className {');
// Fields
for (final f in fields) {
if ((f.description ?? '').isNotEmpty) {
b.writeln(' /// ${f.description}');
}
b.writeln(' final ${f.type} ${f.fieldName};');
}
// Additional properties: collect unknown keys if additionalProperties allowed
final allowAdditional = def.containsKey('additionalProperties');
if (allowAdditional) {
b.writeln(' /// Unrecognized properties captured here.');
b.writeln(' final Map<String, dynamic>? additionalProperties;');
}
b.writeln();
// Constructor
b.writeln(' const $className({');
for (final f in fields) {
final req = f.nullable ? '' : 'required ';
b.writeln(' $req this.${f.fieldName},');
}
if (allowAdditional) {
b.writeln(' this.additionalProperties,');
}
b.writeln(' });\n');
// fromJson
b.writeln(' factory $className.fromJson(Map<String, dynamic> json) {');
if (allowAdditional) b.writeln(' final extras = <String, dynamic>{};');
for (final f in fields) {
final read = "json['${f.jsonKey}']";
// Primitive / list / ref handling (shallow), try to detect $ref kinds
String parse;
if (f.type.endsWith('?')) {
final base = f.type.substring(0, f.type.length - 1);
parse = _jsonReadExpr(base, read, allDefs, false);
} else {
parse = _jsonReadExpr(f.type, read, allDefs, true);
}
b.writeln(' final _${f.fieldName} = $parse;');
}
// gather extras
if (allowAdditional) {
b.writeln(' for (final entry in json.entries) {');
if (fields.isEmpty) {
b.writeln(' extras[entry.key] = entry.value;');
} else {
final keys = fields.map((f) => "'${f.jsonKey}'").join(', ');
b.writeln(' if (!{ $keys }.contains(entry.key)) {');
b.writeln(' extras[entry.key] = entry.value;');
b.writeln(' }');
}
b.writeln(' }');
}
b.writeln(' return $className(');
for (final f in fields) {
b.writeln(' ${f.fieldName}: _${f.fieldName},');
}
if (allowAdditional) {
b.writeln(' additionalProperties: extras.isEmpty ? null : extras,');
}
b.writeln(' );');
b.writeln(' }\n');
// toJson
b.writeln(' Map<String, dynamic> toJson() {');
b.writeln(' final _json = <String, dynamic>{};');
for (final f in fields) {
final writeExpr = _jsonWriteExpr(f.type, f.fieldName, allDefs);
if (f.nullable) {
b.writeln(" if (${f.fieldName} != null) {");
b.writeln(" _json['${f.jsonKey}'] = $writeExpr;");
b.writeln(' }');
} else {
b.writeln(" _json['${f.jsonKey}'] = $writeExpr;");
}
}
if (allowAdditional) {
b.writeln(' if (additionalProperties != null) {');
b.writeln(' _json.addAll(additionalProperties!);');
b.writeln(' }');
}
b.writeln(' return _json;');
b.writeln(' }');
b.writeln('}\n');
return b.toString();
}