generateFromConstructors function
Implementation
Future<Library> generateFromConstructors(
InterfaceElement clazz,
GeneratorCtx ctx,
) async {
final inputConfig = inputTypeAnnotation(clazz);
final hasFrezzed = freezedTypeChecker.hasAnnotationOfExact(clazz);
final _annot =
const TypeChecker.fromRuntime(GraphQLUnion).firstAnnotationOfExact(clazz);
final classAnnot = getClassConfig(ctx, clazz);
final annot = _annot == null
? null
: GraphQLUnion(
name: _annot.getField('name')?.toStringValue(),
unnestIfEqual: _annot.getField('unnestIfEqual')?.toBoolValue(),
);
final variants = await freezedVariants(
clazz,
ctx,
isInput: inputConfig != null,
);
if (inputConfig != null &&
(inputConfig.constructor != null || variants.length > 1)) {
final constructor = inputConfig.constructor ?? '';
variants.removeWhere((v) => v.constructorName != constructor);
}
if (inputConfig != null && variants.length != 1) {
if (inputConfig.constructor == null) {
throw Exception(
'A class annotated with @GraphQLInput should only have one constructor'
' or the `GraphQLInput.constructor` parameter should be set.',
);
} else {
throw Exception(
'Could not find constructor "${inputConfig.constructor}" for'
' @GraphQLInput annotated class "${clazz.name}".'
' Available constructors: ${variants.map((v) => v.constructorName).join(', ')}',
);
}
}
final _classLib = classAnnot != null && inputConfig != null
? await generateObjectFromFields(ctx, clazz)
: null;
return Library((l) {
// l.directives.addAll(
// ctx.config.customTypes.map((e) => Directive.import(e.import)),
// );
if (_classLib != null) {
l.replace(_classLib);
}
if (hasFrezzed || inputConfig != null) {
/// We need to generate each Object variant for freezed annotated classes
for (final variant in variants) {
if (_classLib == null) {
// `variant.serializer()` is already present in _classLib for inputs
l.body.add(variant.serializer());
}
l.body.add(Code(variant.typeDefinitionCode()));
}
}
if (variants.length == 1 && annot == null) {
/// if it's a single freezed constructor, don't generate the union
return;
}
final className = clazz.name;
final fieldName = '${ReCase(className).camelCase}$graphqlTypeSuffix';
final description = getDescription(clazz, clazz.documentationComment);
final attachments = getAttachments(clazz);
l.body.add(Code('''
${hasFromJson(clazz) ? serializerDefinitionCode(className, hasFrezzed: false) : ''}
/// Generated from [$className]
GraphQLUnionType<$className> get $fieldName => _$fieldName.value;
final _$fieldName = HotReloadableDefinition<GraphQLUnionType<$className>>((setValue) {
final type = GraphQLUnionType<$className>(
'${annot?.name ?? className}',
const [],
${description == null ? '' : "description: '$description',"}
${attachments == null ? '' : 'extra: GraphQLTypeDefinitionExtra.attach($attachments),'}
);
setValue(type);
type.possibleTypes.addAll([
${variants.map((e) => e.fieldName).join(',')},
]);
return type;
});
'''));
// Map<String, Object?> _\$${typeName}ToJson($typeName instance) => instance.toJson();
// GraphQLObjectField<String, String, P>
// $fieldName$unionKeySuffix<P extends $typeName>()
// => field(
// 'runtimeType',
// enumTypeFromStrings('${typeName}Type', [
// ${variants.map((e) => '"${e.constructorName}"').join(',')}
// ]),
// );
});
}