Files
cherrypick/cherrypick_generator/lib/inject_generator.dart
2025-05-23 12:21:23 +03:00

66 lines
2.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'package:build/build.dart';
import 'package:collection/collection.dart';
import 'package:source_gen/source_gen.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:cherrypick_annotations/cherrypick_annotations.dart' as ann;
class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
const InjectGenerator();
@override
FutureOr<String> generateForAnnotatedElement(
Element element, ConstantReader annotation, BuildStep buildStep) {
// Only classes are supported for @module() annotation
// Обрабатываются только классы (другие элементы — ошибка)
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';
final injectedFields = classElement.fields.where((field) => field.metadata
.any((m) =>
m.computeConstantValue()?.type?.getDisplayString() == 'inject'));
// Генерируем инициализацию для каждого поля с аннотацией @inject()
final buffer = StringBuffer();
buffer.writeln('mixin $mixinName {');
buffer.writeln(' void _inject($className instance) {');
for (final field in injectedFields) {
// Получаем имя типа
final fieldType = field.type.getDisplayString();
// Ищем аннотацию @named
final namedAnnotation = field.metadata.firstWhereOrNull(
(m) => m.computeConstantValue()?.type?.getDisplayString() == 'named',
);
String namedParam = '';
if (namedAnnotation != null) {
final namedValue = namedAnnotation
.computeConstantValue()
?.getField('value')
?.toStringValue();
if (namedValue != null) {
namedParam = "(named: '$namedValue')";
}
}
buffer.writeln(
" instance.${field.name} = CherryPick.openRootScope().resolve<$fieldType>$namedParam;");
}
buffer.writeln(' }');
buffer.writeln('}');
return buffer.toString();
}
}
Builder injectBuilder(BuilderOptions options) =>
PartBuilder([InjectGenerator()], '.inject.cherrypick.g.dart');