generateModelClass function
Implementation
bool generateModelClass(
String srcDir,
String distDir,
String tag, {
required bool nullable,
}) {
if (srcDir.endsWith("/")) srcDir = srcDir.substring(0, srcDir.length - 1);
if (distDir.endsWith("/")) distDir = distDir.substring(0, distDir.length - 1);
final src = Directory(srcDir);
final fileList = src.listSync(recursive: true);
// String indexFile = "";
if (fileList.isEmpty) return false;
if (!Directory(distDir).existsSync()) {
Directory(distDir).createSync(recursive: true);
}
File file;
fileList.forEach((f) {
if (FileSystemEntity.isFileSync(f.path)) {
file = File(f.path);
final ext = path.extension(f.path);
final String fileName = path.basenameWithoutExtension(f.path);
final jsonExt = ".json";
final json5Ext = ".json5";
final isJson = ext.toLowerCase() == jsonExt;
final isJson5 = ext.toLowerCase() == json5Ext;
if ((!isJson && !isJson5) || fileName.startsWith("_")) return;
final relative = path.relative(f.path, from: srcDir);
final dartFilePath =
path.join(distDir, path.setExtension(relative, ".dart"));
final json = json5Decode(file.readAsStringSync());
//generated class name
final className = fileName.underlineToHumpNaming(true);
var classes = List<Class>.empty(growable: true);
if (json is List) {
handleList(classes, className, json);
} else if (json is Map<String, dynamic>) {
handleClass(classes, className, json);
classes.forEach((c) {
c.fields.forEach((f) {
if (f.type == "Null") {
f.type = "dynamic";
f.nullable = true;
}
});
});
}
classes = classes.toSet().toList();
// To ensure that import statements are not repeated,
// we use Set to save import statements
final importSet = Set<String>();
importSet.add(jsonAnnotation);
// Insert the imports at the head of dart file.
var _import = importSet.join(";\r\n");
_import += _import.isEmpty ? "" : ";";
final classesStr = StringBuffer();
final topClassIndex = classes.indexWhere((c) => c.name == className);
final topClass = classes[topClassIndex];
classes
..removeAt(topClassIndex)
..insert(0, topClass);
classes.forEach((c) {
final constructor = StringBuffer();
constructor.write("${c.name}(\n {");
final fieldsStr = StringBuffer();
var i = 0;
c.fields.forEach((f) {
if (f.nullable && f.type != "dynamic") {
f.type = f.type + "?";
}
final required = f.nullable ? "" : "required ";
final pad = i == 0 ? "" : " ";
final constructorField = "${pad}${required}this.${f.name},\n";
String? defaultValue = null;
if (f.type == "String") {
defaultValue = "\"\"";
} else if (f.type == "int") {
defaultValue = "0";
} else if (f.type == "double") {
defaultValue = "0.0";
} else if (f.type.startsWith("List<")) {
defaultValue = "[]";
} else if (f.type == "bool") {
defaultValue = "false";
}
final defaultValueStr =
defaultValue != null ? ", defaultValue: ${defaultValue}" : "";
constructor.write(constructorField);
// final late = f.nullable ? "" : "late ";
fieldsStr
.write(" @JsonKey(name: \"${f.rawName}\"$defaultValueStr)\n");
fieldsStr.write(" ${f.type} ${f.name};\n");
i++;
});
var constructorStr = constructor.toString();
constructorStr =
constructorStr.substring(0, constructorStr.length - 2) + "});";
classesStr.write(replaceTemplate(tpl, [
c.name,
constructorStr,
fieldsStr.toString(),
c.name,
c.name,
c.name,
]));
});
String topListFunction = "";
if (json is List) {
topListFunction = replaceTemplate(topListTpl, [
className,
className.firstToLowerCase(),
className,
className.firstToLowerCase(),
className
]);
}
final body = topListFunction.isNotEmpty
? topListFunction + "\n\n" + classesStr.toString()
: classesStr.toString();
final dist = (replaceTemplate(dartFileTpl,
[_import, path.basenameWithoutExtension(dartFilePath), body]));
File(dartFilePath)
..createSync(recursive: true)
..writeAsStringSync(dist);
// indexFile = exportIndexFile(
// className, json is List, dartFilePath, distDir, indexFile);
print('done: ${f.path} -> $dartFilePath');
}
});
// if (indexFile.isNotEmpty) {
// final p = path.join(distDir, "index.dart");
// File(p).writeAsStringSync(indexFile);
// print('create index file: $p');
// }
print("src directory:" + path.canonicalize(srcDir));
print("dist directory:" + path.canonicalize(distDir));
return true;
}