generateModelClass function

bool generateModelClass(
  1. String srcDir,
  2. String distDir,
  3. String tag, {
  4. required bool nullable,
})

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;
}