feat: implement tryResolve via generate code

This commit is contained in:
Sergey Penkovsky
2025-06-04 00:38:23 +03:00
parent dd608031a2
commit a9260e0413
2 changed files with 27 additions and 6 deletions

View File

@@ -13,6 +13,7 @@
import 'dart:async'; import 'dart:async';
import 'package:analyzer/dart/constant/value.dart'; import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/dart/element/type.dart';
import 'package:build/build.dart'; import 'package:build/build.dart';
import 'package:source_gen/source_gen.dart'; import 'package:source_gen/source_gen.dart';
@@ -119,10 +120,20 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
isFuture = false; isFuture = false;
} }
// ***
// Добавим определение nullable для типа (например PostRepository? или Future<PostRepository?>)
bool isNullable = dartType.nullabilitySuffix ==
NullabilitySuffix.question ||
(dartType is ParameterizedType &&
(dartType)
.typeArguments
.any((t) => t.nullabilitySuffix == NullabilitySuffix.question));
return _ParsedInjectField( return _ParsedInjectField(
fieldName: field.name, fieldName: field.name,
coreType: coreTypeName, coreType: coreTypeName.replaceAll('?', ''), // удаляем "?" на всякий
isFuture: isFuture, isFuture: isFuture,
isNullable: isNullable,
scopeName: scopeName, scopeName: scopeName,
namedValue: namedValue, namedValue: namedValue,
); );
@@ -134,17 +145,24 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
/// Генерирует строку кода, которая внедряет зависимость для поля. /// Генерирует строку кода, которая внедряет зависимость для поля.
/// Учитывает resolve/resolveAsync, scoping и named qualifier. /// Учитывает resolve/resolveAsync, scoping и named qualifier.
String _generateInjectionLine(_ParsedInjectField field) { String _generateInjectionLine(_ParsedInjectField field) {
final methodName = field.isFuture // Используем tryResolve для nullable, иначе resolve
? 'resolveAsync<${field.coreType}>' final resolveMethod = field.isFuture
: 'resolve<${field.coreType}>'; ? (field.isNullable
? 'tryResolveAsync<${field.coreType}>'
: 'resolveAsync<${field.coreType}>')
: (field.isNullable
? 'tryResolve<${field.coreType}>'
: 'resolve<${field.coreType}>');
final openCall = (field.scopeName != null && field.scopeName!.isNotEmpty) final openCall = (field.scopeName != null && field.scopeName!.isNotEmpty)
? "CherryPick.openScope(scopeName: '${field.scopeName}')" ? "CherryPick.openScope(scopeName: '${field.scopeName}')"
: "CherryPick.openRootScope()"; : "CherryPick.openRootScope()";
final params = (field.namedValue != null && field.namedValue!.isNotEmpty) final params = (field.namedValue != null && field.namedValue!.isNotEmpty)
? "(named: '${field.namedValue}')" ? "(named: '${field.namedValue}')"
: '()'; : '()';
return " instance.${field.fieldName} = $openCall.$methodName$params;"; return " instance.${field.fieldName} = $openCall.$resolveMethod$params;";
} }
} }
@@ -170,10 +188,13 @@ class _ParsedInjectField {
/// Optional named annotation argument / Опциональное имя named. /// Optional named annotation argument / Опциональное имя named.
final String? namedValue; final String? namedValue;
final bool isNullable;
_ParsedInjectField({ _ParsedInjectField({
required this.fieldName, required this.fieldName,
required this.coreType, required this.coreType,
required this.isFuture, required this.isFuture,
required this.isNullable,
this.scopeName, this.scopeName,
this.namedValue, this.namedValue,
}); });

View File

@@ -165,7 +165,7 @@ packages:
path: "../../cherrypick_generator" path: "../../cherrypick_generator"
relative: true relative: true
source: path source: path
version: "1.1.0-dev.3" version: "1.1.0-dev.4"
clock: clock:
dependency: transitive dependency: transitive
description: description: