parseMetadata property

AnalysisResult get parseMetadata

JSON decode current file and return CustomType.

The JSON is expected to contain metadata for a single data class.

Implementation

AnalysisResult get parseMetadata {
  final enumTypes = <EnumType>[];
  final customTypes = <CustomType>[];
  final json = readAsStringSync().jsonDecode;
  final className = json.stringNode("className").data;

  if (json.hasKey("members")) {
    final data = json.arrayOrNull<dynamic>("members");
    if (data != null) {
      final members = <TypeMember>[];

      for (final object in data) {
        final name = object["name"] as String;
        final type = object["type"] as String;
        final nullable = object["nullable"] as bool;

        final memberType = type.toAbstractType(nullable: nullable);

        if (memberType is CustomType || memberType is EnumType) {
          final debugFile = parent.resolve(
              "$metadataMarkerPrefix${memberType.className.toLowerCase()}.json");
          if (debugFile.existsSync()) {
            final result = debugFile.parseMetadata;
            final parentOrNull = result.parent;
            if (parentOrNull is CustomType) {
              customTypes.add(parentOrNull);
            }
            if (parentOrNull is EnumType) {
              enumTypes.add(parentOrNull);
            }
            customTypes.addAll(result.childrenCustomTypes);
            enumTypes.addAll(result.childrenEnumTypes);
          } else {
            "Found ${memberType.runtimeType} but no source (Does not exist: ${debugFile.path})"
                .log();
          }
        }

        members.add(
          TypeMember(
            name: name,
            type: memberType,
          ),
        );
      }

      return AnalysisResult(
        parent: CustomType(
          className: className,
          members: members,
        ),
        childrenCustomTypes: customTypes.toSet(),
        childrenEnumTypes: enumTypes.toSet(),
      ).normalizeParentTypeMembers;
    }
  }

  if (json.hasKey("values")) {
    final values = json.arrayOrNull<String>("values") ?? [];
    final valuesJSON = json.hasKey("valuesJSON")
        ? json.arrayOrNull<String>("valuesJSON") ?? <String>[]
        : <String>[];

    final enumType = EnumType(
      className: className,
      values: values,
      valuesJSON: valuesJSON,
    );

    enumTypes.add(enumType);
    return AnalysisResult(
      parent: null,
      childrenCustomTypes: customTypes.toSet(),
      childrenEnumTypes: enumTypes.toSet(),
    );
  }

  "Example of CustomType metadata JSON file:".log(context: """
  {
  "className": "MyResponse",
  "members": [
    {
        "name": "a1",
        "type": "int",
        "nullable": false
    },
    {
          "name": "a2",
          "type": "String",
          "nullable": true
    }
  ]
}""");
  "Example of EnumType metadata JSON file:".log(context: """
  {
      "className": "MyResponse",
      "values": [
        "FOO",
        "BAR"
      ],
      "valuesJSON": [
        "foo",
        "bar"
      ],
    }""");

  throw SquintException("Unable to parse metadata file.");
}