generateForAnnotatedElement method
dynamic
generateForAnnotatedElement(
- Element element,
- ConstantReader annotation,
- BuildStep buildStep
Main entry point for CherryPick field injection code generation.
- Only triggers for classes marked with
@injectable(). - Throws an error if used on non-class elements.
- Scans all fields marked with
@inject()and gathers qualifiers (if any). - Generates Dart code for a mixin that injects all dependencies into the target class instance.
Returns the Dart code as a String defining the new mixin.
Example input (user code):
@injectable()
class UserBloc with _$UserBloc {
@inject() late final AuthRepository authRepository;
}
Example output (generated):
mixin _$UserBloc {
void _inject(UserBloc instance) {
instance.authRepository = CherryPick.openRootScope().resolve<AuthRepository>();
}
}
Implementation
@override
dynamic generateForAnnotatedElement(
Element element,
ConstantReader annotation,
BuildStep buildStep,
) {
if (element is! ClassElement) {
throw InvalidGenerationSourceError(
'@injectable() can only be applied to classes.',
element: element,
);
}
final classElement = element;
final className = classElement.name;
final mixinName = '_\$$className';
AnnotationValidator.validateClassAnnotations(classElement);
final classType = TypeParser.parseType(classElement.thisType, classElement);
// Collect and process all @inject fields
final injectFields = classElement.fields
.where((f) => _isInjectField(f))
.map(_parseInjectField)
.toList();
final injectMethod = Method((b) {
b
..name = '_inject'
..returns = refer('void')
..requiredParameters.add(
Parameter((p) {
p
..name = 'instance'
..type = CodeBuilderEmitters.resolveTypeRef(classType);
}),
)
..body = Block((body) {
for (final field in injectFields) {
final scopeExpr = CodeBuilderEmitters.openScope(
scopeName: field.scopeName,
);
final resolveExpr = CodeBuilderEmitters.resolveCall(
scopeExpr: scopeExpr,
parsedType: field.parsedType,
named: field.namedValue,
);
body.statements.add(
refer(
'instance',
).property(field.fieldName).assign(resolveExpr).statement,
);
}
});
});
final mixin = Mixin((b) {
b
..name = mixinName
..methods.add(injectMethod);
});
final library = Library((b) => b..body.add(mixin));
final emitter = DartEmitter(useNullSafetySyntax: true);
return '${library.accept(emitter)}';
}