toTupleClass function
Implementation
Spec toTupleClass(
String className,
ts.ObjectType obj,
GenOption option,
) {
final constructorParameters = <Parameter>[];
final fromJson = StringBuffer();
final toJson = StringBuffer();
final toJsonFields = StringBuffer();
final hashes = <String>[];
final equals = <String>[];
final fields = <Field>[];
final copyWithParameters = <Parameter>[];
final copyWithAssign = StringBuffer();
obj.children.forEachIndexed((index, e) {
final child = e.child;
final fieldName = 'item${index + 1}';
final isOpt = child is ts.OptType;
var dartType = child.dartType();
if (isOpt && !dartType.endsWith('?')) {
dartType += '?';
}
final isList = dartType.startsWith('List<');
if (isList) {
hashes.add('const DeepCollectionEquality().hash($fieldName)');
equals.add(
'const DeepCollectionEquality().equals(other.$fieldName, $fieldName)',
);
} else {
hashes.add(fieldName);
equals.add(
'(identical(other.$fieldName, $fieldName) || other.$fieldName == $fieldName)',
);
}
final type = Reference(dartType);
constructorParameters.add(
Parameter(
(b) => b
..toThis = true
..name = fieldName,
),
);
copyWithParameters.add(
Parameter(
(b) => b
..name = fieldName
..named = true
..docs = ListBuilder(
['/// [$fieldName] defined in Candid: `${child.did}`'],
)
..type = Reference(dartType.endsWith('?') ? dartType : '$dartType?'),
),
);
copyWithAssign.writeln('$fieldName ?? this.$fieldName,');
fields.add(
Field(
(b) => b
..name = fieldName
..type = type
..modifier = FieldModifier.final$
..docs = ListBuilder(
['/// [$fieldName] defined in Candid: `${child.did}`'],
),
),
);
var deserialize = child.deserialize();
if (deserialize != null) {
deserialize = deserialize.replaceAll(ts.IDLType.ph, 'tuple[$index]');
} else {
deserialize = 'tuple[$index]';
}
fromJson.writeln('$deserialize,');
final ser = child.serialize();
final arg =
ser == null ? fieldName : ser.replaceAll(ts.IDLType.ph, fieldName);
toJson.writeln('$arg,');
toJsonFields.writeln('final $fieldName = this.$fieldName;');
});
return Class(
(b) => b
..name = className
..annotations = ListBuilder([const CodeExpression(Code('immutable'))])
..constructors = ListBuilder([
Constructor(
(b) => b
..requiredParameters = ListBuilder(constructorParameters)
..constant = true,
),
Constructor(
(b) => b
..name = 'fromJson'
..factory = true
..body = Code('return $className($fromJson);')
..requiredParameters = ListBuilder([
Parameter(
(b) => b
..type = const Reference('List<dynamic>')
..name = 'tuple',
),
]),
),
])
..fields = ListBuilder(fields)
..methods = ListBuilder([
Method(
(b) => b
..name = 'toJson'
..body = Code('${toJsonFields}return [$toJson];')
..returns = const Reference('List<dynamic>'),
),
if (option.copyWith)
Method(
(b) => b
..name = 'copyWith'
..optionalParameters = ListBuilder(copyWithParameters)
..body = Code('return $className($copyWithAssign);')
..returns = Reference(className),
),
if (option.equal) ...[
Method(
(b) => b
..name = 'operator =='
..returns = const Reference('bool')
..requiredParameters = ListBuilder([
Parameter(
(b) => b
..name = 'other'
..type = const Reference('Object'),
),
])
..annotations =
ListBuilder([const CodeExpression(Code('override'))])
..body = Code(
'return identical(this, other) '
'|| (other.runtimeType == runtimeType && other is $className ${fields.isEmpty ? '' : '&&'} '
'${equals.join("&&")});',
),
),
Method(
(b) => b
..type = MethodType.getter
..name = 'hashCode'
..returns = const Reference('int')
..lambda = true
..annotations =
ListBuilder([const CodeExpression(Code('override'))])
..body =
Code('Object.hashAll([runtimeType,${hashes.join(",")}])'),
),
],
toStringMethod,
])
..docs = ListBuilder(['/// [$className] defined in Candid', obj.doc]),
);
}