mirror of
https://github.com/pese-git/cherrypick.git
synced 2026-01-23 21:13:35 +00:00
refactor inject generator
This commit is contained in:
@@ -11,7 +11,10 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<String> generateForAnnotatedElement(
|
FutureOr<String> generateForAnnotatedElement(
|
||||||
Element element, ConstantReader annotation, BuildStep buildStep) {
|
Element element,
|
||||||
|
ConstantReader annotation,
|
||||||
|
BuildStep buildStep,
|
||||||
|
) {
|
||||||
if (element is! ClassElement) {
|
if (element is! ClassElement) {
|
||||||
throw InvalidGenerationSourceError(
|
throw InvalidGenerationSourceError(
|
||||||
'@injectable() can only be applied to classes.',
|
'@injectable() can only be applied to classes.',
|
||||||
@@ -23,20 +26,39 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
|
|||||||
final className = classElement.name;
|
final className = classElement.name;
|
||||||
final mixinName = '_\$$className';
|
final mixinName = '_\$$className';
|
||||||
|
|
||||||
final injectedFields = classElement.fields.where((field) => field.metadata
|
final buffer = StringBuffer()
|
||||||
.any((m) =>
|
..writeln('mixin $mixinName {')
|
||||||
m.computeConstantValue()?.type?.getDisplayString() == 'inject'));
|
..writeln(' void _inject($className instance) {');
|
||||||
|
|
||||||
final buffer = StringBuffer();
|
// Collect and process all @inject fields
|
||||||
buffer.writeln('mixin $mixinName {');
|
final injectFields =
|
||||||
buffer.writeln(' void _inject($className instance) {');
|
classElement.fields.where(_isInjectField).map(_parseInjectField);
|
||||||
|
|
||||||
for (final field in injectedFields) {
|
for (final parsedField in injectFields) {
|
||||||
|
buffer.writeln(_generateInjectionLine(parsedField));
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer
|
||||||
|
..writeln(' }')
|
||||||
|
..writeln('}');
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if a field has @inject annotation
|
||||||
|
static bool _isInjectField(FieldElement field) {
|
||||||
|
return field.metadata.any(
|
||||||
|
(m) => m.computeConstantValue()?.type?.getDisplayString() == 'inject',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parsed structure storage
|
||||||
|
static _ParsedInjectField _parseInjectField(FieldElement field) {
|
||||||
String? scopeName;
|
String? scopeName;
|
||||||
String? namedValue;
|
String? namedValue;
|
||||||
|
|
||||||
for (final m in field.metadata) {
|
for (final meta in field.metadata) {
|
||||||
final DartObject? obj = m.computeConstantValue();
|
final DartObject? obj = meta.computeConstantValue();
|
||||||
final type = obj?.type?.getDisplayString();
|
final type = obj?.type?.getDisplayString();
|
||||||
if (type == 'scope') {
|
if (type == 'scope') {
|
||||||
scopeName = obj?.getField('name')?.toStringValue();
|
scopeName = obj?.getField('name')?.toStringValue();
|
||||||
@@ -45,39 +67,58 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Фикс: определяем resolveAsync для Future<T> ---
|
final DartType dartType = field.type;
|
||||||
final DartType type = field.type;
|
String coreTypeName;
|
||||||
String genericType;
|
bool isFuture;
|
||||||
String resolveMethod;
|
|
||||||
|
|
||||||
if (type.isDartAsyncFuture) {
|
if (dartType.isDartAsyncFuture) {
|
||||||
// Если поле Future<T>
|
final ParameterizedType paramType = dartType as ParameterizedType;
|
||||||
final typeArg = (type as ParameterizedType).typeArguments.first;
|
coreTypeName = paramType.typeArguments.first.getDisplayString();
|
||||||
genericType = typeArg.getDisplayString();
|
isFuture = true;
|
||||||
resolveMethod = 'resolveAsync<$genericType>';
|
|
||||||
} else {
|
} else {
|
||||||
genericType = type.getDisplayString();
|
coreTypeName = dartType.getDisplayString();
|
||||||
resolveMethod = 'resolve<$genericType>';
|
isFuture = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Вызываем openScope или openRootScope
|
return _ParsedInjectField(
|
||||||
String accessor = (scopeName != null && scopeName.isNotEmpty)
|
fieldName: field.name,
|
||||||
? "CherryPick.openScope(scopeName: '$scopeName').$resolveMethod"
|
coreType: coreTypeName,
|
||||||
: "CherryPick.openRootScope().$resolveMethod";
|
isFuture: isFuture,
|
||||||
|
scopeName: scopeName,
|
||||||
|
namedValue: namedValue,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Аргументы resolve
|
// Generates the injection invocation line for the field
|
||||||
String params = (namedValue != null && namedValue.isNotEmpty)
|
String _generateInjectionLine(_ParsedInjectField field) {
|
||||||
? "(named: '$namedValue')"
|
final methodName = field.isFuture
|
||||||
|
? 'resolveAsync<${field.coreType}>'
|
||||||
|
: 'resolve<${field.coreType}>';
|
||||||
|
final openCall = (field.scopeName != null && field.scopeName!.isNotEmpty)
|
||||||
|
? "CherryPick.openScope(scopeName: '${field.scopeName}')"
|
||||||
|
: "CherryPick.openRootScope()";
|
||||||
|
final params = (field.namedValue != null && field.namedValue!.isNotEmpty)
|
||||||
|
? "(named: '${field.namedValue}')"
|
||||||
: '()';
|
: '()';
|
||||||
|
|
||||||
buffer.writeln(" instance.${field.name} = $accessor$params;");
|
return " instance.${field.fieldName} = $openCall.$methodName$params;";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buffer.writeln(' }');
|
class _ParsedInjectField {
|
||||||
buffer.writeln('}');
|
final String fieldName;
|
||||||
|
final String coreType;
|
||||||
|
final bool isFuture;
|
||||||
|
final String? scopeName;
|
||||||
|
final String? namedValue;
|
||||||
|
|
||||||
return buffer.toString();
|
_ParsedInjectField({
|
||||||
}
|
required this.fieldName,
|
||||||
|
required this.coreType,
|
||||||
|
required this.isFuture,
|
||||||
|
this.scopeName,
|
||||||
|
this.namedValue,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder injectBuilder(BuilderOptions options) =>
|
Builder injectBuilder(BuilderOptions options) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user