toFreezedClass function
Implementation
Spec toFreezedClass(String className, ts.ObjectType obj, GenOption option) {
final isVariant = obj.isVariant;
final optionalParameters = <Parameter>[];
final fromJson = StringBuffer();
final toJson = StringBuffer();
final toJsonFields = StringBuffer();
for (final e in obj.children) {
final child = e.child;
final idlName = child.id!;
var fieldName = idlName.camelCase;
if (kDartKeywordsAndInternalTypes.contains(fieldName)) {
fieldName += '_';
}
final isNumberKey = RegExp(r'^\d+$').hasMatch(fieldName);
if (isNumberKey) {
fieldName = '\$$fieldName';
}
final isIdType = child is ts.IdType;
var dartType = child.dartType();
final useBool = (isIdType && isVariant) || dartType == 'null';
final isOpt = isIdType ||
(child as ts.PairType).value.child is ts.OptType ||
isVariant;
if (isOpt && !dartType.endsWith('?')) {
dartType += '?';
}
final refType = Reference(useBool ? 'bool' : dartType);
final parameter = Parameter(
(b) => b
..named = true
..type = refType
..required = !isOpt
..annotations = ListBuilder(
useBool ? [const CodeExpression(Code('Default(false)'))] : [],
)
..docs = ListBuilder(
['/// [$fieldName] defined in Candid: `${child.did}`'],
)
..name = fieldName,
);
optionalParameters.add(parameter);
if (useBool) {
fromJson.writeln("$fieldName: json.containsKey('$idlName'),");
toJson.writeln("if ($fieldName) '$idlName': null,");
} else {
var deser = child.deserialize(nullable: isOpt);
if (deser != null) {
if (isNumberKey) {
deser = deser.replaceAll(ts.IDLType.ph, 'json[$idlName]');
} else {
deser = deser.replaceAll(ts.IDLType.ph, "json['$idlName']");
}
} else {
if (isNumberKey) {
deser = 'json[$idlName]';
} else {
deser = "json['$idlName']";
}
}
fromJson.writeln('$fieldName: $deser,');
final ser = child.serialize();
final arg =
ser == null ? fieldName : ser.replaceAll(ts.IDLType.ph, fieldName);
var isOptChild = false;
if (child is ts.PairType) {
final value = child.value.child;
isOptChild = value is ts.OptType ||
(value is ts.IdType &&
value.child is ts.Id &&
(value.child as ts.Id).isOpt);
}
if ((!isVariant && isOptChild) || !isOpt) {
if (isNumberKey) {
toJson.writeln('$idlName: $arg,');
} else {
toJson.writeln("'$idlName': $arg,");
}
} else {
if (isNumberKey) {
toJson.writeln('if ($fieldName != null) $idlName: $arg,');
} else {
toJson.writeln("if ($fieldName != null) '$idlName': $arg,");
}
}
}
toJsonFields.writeln('final $fieldName = this.$fieldName;');
}
return Class(
(b) => b
..name = className
..mixins = ListBuilder([Reference('_\$$className')])
..annotations = ListBuilder([CodeExpression(Code(option.annotation))])
..constructors = ListBuilder([
Constructor(
(b) => b
..name = '_'
..constant = true,
),
Constructor(
(b) => b
..optionalParameters = ListBuilder(optionalParameters)
..redirect = Reference('_$className')
..factory = true
..constant = true,
),
Constructor(
(b) => b
..name = 'fromJson'
..factory = true
..body = Code('return ${obj.ctx.getClassName()}($fromJson);')
..requiredParameters = ListBuilder([
Parameter(
(b) => b
..type = const Reference('Map')
..name = 'json',
),
]),
),
])
..methods = ListBuilder([
Method(
(b) => b
..name = 'toJson'
..body = Code('${toJsonFields}return { $toJson };')
..returns = const Reference('Map<String, dynamic>'),
),
toStringMethod,
])
..docs = ListBuilder(['/// [$className] defined in Candid', obj.doc]),
);
}