structurizeConstructor function
Future<StructurizeResult>
structurizeConstructor(
- DartType type,
- DogsGeneratorSettings settings,
- ConstructorElement2 constructorElement,
- SubjectGenContext<
Element2> context, - CachedAliasCounter counter,
Implementation
Future<StructurizeResult> structurizeConstructor(
DartType type,
DogsGeneratorSettings settings,
ConstructorElement2 constructorElement,
SubjectGenContext<Element2> context,
CachedAliasCounter counter) async {
List<AliasImport> imports = [];
List<IRStructureField> fields = [];
var element = type.element3! as ClassElement2;
var serialName = element.displayName;
serialName = settings.nameCase.recase(serialName);
// Check for Serializable annotation and override serialName if applicable
if (serializableChecker.hasAnnotationOf(element)) {
var annotation = serializableChecker.annotationsOf(element).first;
var overrideName = annotation.getField("serialName")?.toStringValue();
if (overrideName != null) {
serialName = overrideName;
}
}
// Determine used constructor
var constructorName = "";
if (element.getNamedConstructor2("dog") != null) {
constructorElement = element.getNamedConstructor2("dog")!;
constructorName = ".dog";
}
for (var e in constructorElement.formalParameters) {
String? fieldName;
DartType? fieldType;
Element2? fieldElement;
if (e is FieldFormalParameterElement2) {
fieldName = e.displayName;
fieldType = e.type;
fieldElement = e.field2;
} else if (e is SuperFormalParameterElement2) {
FieldFormalParameterElement2 resolveUntilFieldFormal(FormalParameterElement e) {
if (e is FieldFormalParameterElement2) return e;
if (e is SuperFormalParameterElement2) {
return resolveUntilFieldFormal(e.superConstructorParameter2!);
}
throw Exception("Can't resolve super formal field");
}
var field = resolveUntilFieldFormal(e.superConstructorParameter2!).field2;
fieldName = field!.displayName;
fieldType = field.type;
fieldElement = field;
} else {
var parameterType = e.type;
var namedField = element.getField2(e.displayName);
var namedGetter = element.lookUpGetter2(name: e.displayName, library: element.library2);
if (namedField != null && namedGetter == null) {
fieldName = e.displayName;
fieldType = namedField.type;
fieldElement = namedField;
if (parameterType.nullabilitySuffix == NullabilitySuffix.question) {
fieldType = parameterType;
}
} else {
if (namedGetter != null) {
fieldName = e.displayName;
fieldType = namedGetter.returnType;
fieldElement = namedGetter;
if (parameterType.nullabilitySuffix == NullabilitySuffix.question) {
fieldType = parameterType;
}
}
}
}
if (fieldElement == null || fieldName == null || fieldType == null) {
throw Exception(
"Constructor fields must have a backing field or getter with the same name and type. Nullability may vary.");
}
var serialType = await getSerialType(fieldType, context);
var iterableType = await getIterableType(fieldType, context);
var optional = fieldType.nullabilitySuffix == NullabilitySuffix.question;
if (fieldType is DynamicType) optional = true;
var propertyName = fieldName;
propertyName = settings.propertyCase.recase(propertyName);
if (propertyNameChecker.hasAnnotationOf(fieldElement)) {
var annotation = propertyNameChecker.annotationsOf(fieldElement).first;
propertyName = annotation.getField("name")!.toStringValue()!;
}
var propertySerializer = "null";
if (propertySerializerChecker.hasAnnotationOf(fieldElement)) {
var serializerAnnotation = propertySerializerChecker.annotationsOf(fieldElement).first;
propertySerializer = counter.get(serializerAnnotation.getField("type")!.toTypeValue()!);
}
fields.add(IRStructureField(
fieldName,
counter.get(fieldType),
getTypeTree(fieldType).code(counter),
propertySerializer,
counter.get(serialType),
iterableType,
propertyName,
optional,
!isDogPrimitiveType(serialType),
getRetainedAnnotationSourceArray(fieldElement, counter),
mapChecker.isAssignableFrom(fieldType.element3!)));
}
// Create proxy arguments
var getters = fields.map((e) => e.accessor).toList();
var activator =
"return ${counter.get(element.thisType)}$constructorName(${constructorElement.formalParameters.mapIndexed((i, e) {
if (e.isNamed) {
return "${e.displayName}: list[$i]";
} else {
return "list[$i]";
}
}).join(", ")});";
var isDataclass = dataclassChecker.isAssignableFromType(element.thisType);
var structure = IRStructure(
counter.get(type),
isDataclass ? StructureConformity.dataclass : StructureConformity.basic,
serialName,
fields,
getRetainedAnnotationSourceArray(element, counter));
return StructurizeResult(imports, structure, getters, activator);
}