Compare commits

...

4 Commits

Author SHA1 Message Date
Sergey Penkovsky
4953e917c9 Merge branch 'master' into develop 2026-01-15 09:00:10 +03:00
Sergey Penkovsky
cccf460f01 chore(release): publish packages
- cherrypick_annotations@3.0.2-dev.0
 - cherrypick_generator@3.0.2-dev.0
2025-09-09 18:15:03 +03:00
Sergey Penkovsky
0c1ef70b73 feat(examples): update client_app and postly implementation details
- Refactored and updated pages, router, DI modules, and feature implementations in both example projects:
  - client_app: main.dart and my_home_page.dart updated for improved navigation and structure.
  - postly: updated DI wiring, presentation pages, repository implementation, and routing logic.
- Applied small improvements and code consistency changes in the examples.

docs: add new documentation assets and benchmarking script

BREAKING CHANGE:
Examples now reflect the latest changes in the DI framework and are ready for Dart 3.8+ and cherrypick_generator element2 API compatibility.
2025-09-09 18:08:39 +03:00
Sergey Penkovsky
eb6d786600 refactor(generator): migrate cherrypick_generator to analyzer element2 API
- Fully migrated core cherrypick_generator and submodules to new analyzer element2 system:
  - Updated all GeneratorForAnnotation overrides to use Element2, ClassElement2, MethodElement2, FieldElement2 and new annotation/metadata access patterns.
  - Migrated signature and bodies for helpers, parsers, annotation validators, meta utils, and type parsers.
  - Fixed tests to use readerWriter instead of deprecated reader argument.
  - Refactored usage of now-absent 'metadata', 'parameters', 'fields', 'methods', 'source', and similar members to use correct *.firstFragment.* or API alternatives.
  - Cleaned up old imports and unused code.

test(generator): update generator integration tests

- Updated test calls to use correct TestReaderWriter type and bring test infra in line with current build_runner/testing API.

build: update dependencies and pubspec to support latest analyzer/build ecosystem

- Raised Dart SDK and package constraints as required for generated code and codegen plugins.
- Updated pubspecs in root/examples as needed by build warnings.

docs: add plots and assets (new files)

BREAKING CHANGE:
- Requires Dart 3.8+ and analyzer that supports element2.
- All downstream codegen/tests depending on Element API must migrate to Element2 signatures and data model.
2025-09-09 18:08:39 +03:00
32 changed files with 485 additions and 355 deletions

2
.fvmrc
View File

@@ -1,3 +1,3 @@
{
"flutter": "3.27.0"
"flutter": "3.32.0"
}

View File

@@ -34,6 +34,32 @@ Packages with dependency updates only:
- **FIX**(scope): properly clear binding and module references on dispose.
## 2025-09-09
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`cherrypick_annotations` - `v3.0.2-dev.0`](#cherrypick_annotations---v302-dev0)
- [`cherrypick_generator` - `v3.0.2-dev.0`](#cherrypick_generator---v302-dev0)
---
#### `cherrypick_annotations` - `v3.0.2-dev.0`
- **REFACTOR**(generator): migrate cherrypick_generator to analyzer element2 API.
#### `cherrypick_generator` - `v3.0.2-dev.0`
- **REFACTOR**(generator): migrate cherrypick_generator to analyzer element2 API.
## 2025-09-09
### Changes

View File

@@ -1,3 +1,7 @@
## 3.0.2-dev.0
- **REFACTOR**(generator): migrate cherrypick_generator to analyzer element2 API.
## 3.0.1
- **DOCS**: add Netlify deployment status badge to README files.

View File

@@ -1,7 +1,7 @@
name: cherrypick_annotations
description: |
Set of annotations for CherryPick dependency injection library. Enables code generation and declarative DI for Dart & Flutter projects.
version: 3.0.1
version: 3.0.2-dev.0
homepage: https://cherrypick-di.netlify.app
documentation: https://cherrypick-di.netlify.app/docs/intro
repository: https://github.com/pese-git/cherrypick/cherrypick_annotations
@@ -14,7 +14,7 @@ topics:
- inversion-of-control
environment:
sdk: ">=3.6.0 <4.0.0"
sdk: ">=3.8.0 <4.0.0"
# Add regular dependencies here.
dependencies:
@@ -22,5 +22,5 @@ dependencies:
# path: ^1.8.0
dev_dependencies:
lints: ^5.0.0
lints: ^6.0.0
test: ^1.25.8

View File

@@ -1,3 +1,7 @@
## 3.0.2-dev.0
- **REFACTOR**(generator): migrate cherrypick_generator to analyzer element2 API.
## 3.0.1
- **DOCS**: add Netlify deployment status badge to README files.

View File

@@ -11,13 +11,12 @@
// limitations under the License.
//
import 'dart:async';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:build/build.dart';
import 'package:source_gen/source_gen.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:cherrypick_annotations/cherrypick_annotations.dart' as ann;
/// CherryPick DI field injector generator for codegen.
@@ -100,12 +99,12 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
/// }
/// ```
@override
FutureOr<String> generateForAnnotatedElement(
Element element,
dynamic generateForAnnotatedElement(
Element2 element,
ConstantReader annotation,
BuildStep buildStep,
) {
if (element is! ClassElement) {
if (element is! ClassElement2) {
throw InvalidGenerationSourceError(
'@injectable() can only be applied to classes.',
element: element,
@@ -113,7 +112,7 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
}
final classElement = element;
final className = classElement.name;
final className = classElement.firstFragment.name2;
final mixinName = '_\$$className';
final buffer = StringBuffer()
@@ -121,8 +120,9 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
..writeln(' void _inject($className instance) {');
// Collect and process all @inject fields
final injectFields =
classElement.fields.where(_isInjectField).map(_parseInjectField);
final injectFields = classElement.fields2
.where((f) => _isInjectField(f))
.map((f) => _parseInjectField(f));
for (final parsedField in injectFields) {
buffer.writeln(_generateInjectionLine(parsedField));
@@ -138,8 +138,8 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
/// Returns true if a field is annotated with `@inject`.
///
/// Used to detect which fields should be processed for injection.
static bool _isInjectField(FieldElement field) {
return field.metadata.any(
static bool _isInjectField(FieldElement2 field) {
return field.firstFragment.metadata2.annotations.any(
(m) => m.computeConstantValue()?.type?.getDisplayString() == 'inject',
);
}
@@ -149,11 +149,11 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
///
/// Converts Dart field declaration and all parameterizing injection-related
/// annotations into a [_ParsedInjectField] which is used for codegen.
static _ParsedInjectField _parseInjectField(FieldElement field) {
static _ParsedInjectField _parseInjectField(FieldElement2 field) {
String? scopeName;
String? namedValue;
for (final meta in field.metadata) {
for (final meta in field.firstFragment.metadata2.annotations) {
final DartObject? obj = meta.computeConstantValue();
final type = obj?.type?.getDisplayString();
if (type == 'scope') {
@@ -177,15 +177,15 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
}
// Determine nullability for field types like T? or Future<T?>
bool isNullable = dartType.nullabilitySuffix ==
NullabilitySuffix.question ||
bool isNullable =
dartType.nullabilitySuffix == NullabilitySuffix.question ||
(dartType is ParameterizedType &&
(dartType)
.typeArguments
.any((t) => t.nullabilitySuffix == NullabilitySuffix.question));
(dartType).typeArguments.any(
(t) => t.nullabilitySuffix == NullabilitySuffix.question,
));
return _ParsedInjectField(
fieldName: field.name,
fieldName: field.firstFragment.name2 ?? '',
coreType: coreTypeName.replaceAll('?', ''), // удаляем "?" на всякий
isFuture: isFuture,
isNullable: isNullable,
@@ -207,11 +207,11 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
String _generateInjectionLine(_ParsedInjectField field) {
final resolveMethod = field.isFuture
? (field.isNullable
? 'tryResolveAsync<${field.coreType}>'
: 'resolveAsync<${field.coreType}>')
? 'tryResolveAsync<${field.coreType}>'
: 'resolveAsync<${field.coreType}>')
: (field.isNullable
? 'tryResolve<${field.coreType}>'
: 'resolve<${field.coreType}>');
? 'tryResolve<${field.coreType}>'
: 'resolve<${field.coreType}>');
final openCall = (field.scopeName != null && field.scopeName!.isNotEmpty)
? "CherryPick.openScope(scopeName: '${field.scopeName}')"

View File

@@ -11,7 +11,7 @@
// limitations under the License.
//
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:build/build.dart';
import 'package:source_gen/source_gen.dart';
import 'package:cherrypick_annotations/cherrypick_annotations.dart' as ann;
@@ -79,12 +79,12 @@ class ModuleGenerator extends GeneratorForAnnotation<ann.module> {
///
/// See file-level docs for usage and generated output example.
@override
String generateForAnnotatedElement(
Element element,
dynamic generateForAnnotatedElement(
Element2 element,
ConstantReader annotation,
BuildStep buildStep,
) {
if (element is! ClassElement) {
if (element is! ClassElement2) {
throw InvalidGenerationSourceError(
'@module() can only be applied to classes.',
element: element,

View File

@@ -12,6 +12,7 @@
//
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'exceptions.dart';
import 'metadata_utils.dart';
@@ -52,8 +53,10 @@ class AnnotationValidator {
/// - Parameter validation for method arguments.
///
/// Throws [AnnotationValidationException] on any violation.
static void validateMethodAnnotations(MethodElement method) {
final annotations = _getAnnotationNames(method.metadata);
static void validateMethodAnnotations(MethodElement2 method) {
final annotations = _getAnnotationNames(
method.firstFragment.metadata2.annotations,
);
_validateMutuallyExclusiveAnnotations(method, annotations);
_validateAnnotationCombinations(method, annotations);
@@ -68,8 +71,10 @@ class AnnotationValidator {
/// - Correct scope naming if present.
///
/// Throws [AnnotationValidationException] if checks fail.
static void validateFieldAnnotations(FieldElement field) {
final annotations = _getAnnotationNames(field.metadata);
static void validateFieldAnnotations(FieldElement2 field) {
final annotations = _getAnnotationNames(
field.firstFragment.metadata2.annotations,
);
_validateInjectFieldAnnotations(field, annotations);
}
@@ -82,8 +87,10 @@ class AnnotationValidator {
/// - Provides helpful context for error/warning reporting.
///
/// Throws [AnnotationValidationException] if checks fail.
static void validateClassAnnotations(ClassElement classElement) {
final annotations = _getAnnotationNames(classElement.metadata);
static void validateClassAnnotations(ClassElement2 classElement) {
final annotations = _getAnnotationNames(
classElement.firstFragment.metadata2.annotations,
);
_validateModuleClassAnnotations(classElement, annotations);
_validateInjectableClassAnnotations(classElement, annotations);
@@ -104,7 +111,7 @@ class AnnotationValidator {
///
/// For example, `@instance` and `@provide` cannot both be present.
static void _validateMutuallyExclusiveAnnotations(
MethodElement method,
MethodElement2 method,
List<String> annotations,
) {
// @instance and @provide are mutually exclusive
@@ -127,7 +134,7 @@ class AnnotationValidator {
/// - One of `@instance` or `@provide` must be present for a registration method
/// - Validates singleton usage
static void _validateAnnotationCombinations(
MethodElement method,
MethodElement2 method,
List<String> annotations,
) {
// @params can only be used with @provide
@@ -165,7 +172,7 @@ class AnnotationValidator {
/// Singleton-specific method annotation checks.
static void _validateSingletonUsage(
MethodElement method,
MethodElement2 method,
List<String> annotations,
) {
// Singleton with params might not make sense in some contexts
@@ -181,18 +188,17 @@ class AnnotationValidator {
'Singleton methods cannot return void',
element: method,
suggestion: 'Remove @singleton annotation or change return type',
context: {
'method_name': method.displayName,
'return_type': returnType,
},
context: {'method_name': method.displayName, 'return_type': returnType},
);
}
}
/// Validates extra requirements or syntactic rules for annotation arguments, like @named.
static void _validateAnnotationParameters(MethodElement method) {
static void _validateAnnotationParameters(MethodElement2 method) {
// Validate @named annotation parameters
final namedValue = MetadataUtils.getNamedValue(method.metadata);
final namedValue = MetadataUtils.getNamedValue(
method.firstFragment.metadata2.annotations,
);
if (namedValue != null) {
if (namedValue.isEmpty) {
throw AnnotationValidationException(
@@ -222,8 +228,10 @@ class AnnotationValidator {
}
// Validate method parameters for @params usage
for (final param in method.parameters) {
final paramAnnotations = _getAnnotationNames(param.metadata);
for (final param in method.formalParameters) {
final paramAnnotations = _getAnnotationNames(
param.firstFragment.metadata2.annotations,
);
if (paramAnnotations.contains('params')) {
_validateParamsParameter(param, method);
}
@@ -232,7 +240,9 @@ class AnnotationValidator {
/// Checks that @params is used with compatible parameter type.
static void _validateParamsParameter(
ParameterElement param, MethodElement method) {
FormalParameterElement param,
MethodElement2 method,
) {
// @params parameter should typically be dynamic or Map<String, dynamic>
final paramType = param.type.getDisplayString();
if (paramType != 'dynamic' &&
@@ -256,7 +266,7 @@ class AnnotationValidator {
/// Checks field-level annotation for valid injectable fields.
static void _validateInjectFieldAnnotations(
FieldElement field,
FieldElement2 field,
List<String> annotations,
) {
if (!annotations.contains('inject')) {
@@ -270,15 +280,12 @@ class AnnotationValidator {
'Cannot inject void type',
element: field,
suggestion: 'Use a concrete type instead of void',
context: {
'field_name': field.displayName,
'field_type': fieldType,
},
context: {'field_name': field.displayName, 'field_type': fieldType},
);
}
// Validate scope annotation if present
for (final meta in field.metadata) {
for (final meta in field.firstFragment.metadata2.annotations) {
final obj = meta.computeConstantValue();
final type = obj?.type?.getDisplayString();
if (type == 'scope') {
@@ -290,7 +297,7 @@ class AnnotationValidator {
/// Checks @module usage: must have at least one DI method, each with DI-annotation.
static void _validateModuleClassAnnotations(
ClassElement classElement,
ClassElement2 classElement,
List<String> annotations,
) {
if (!annotations.contains('module')) {
@@ -298,8 +305,9 @@ class AnnotationValidator {
}
// Check if class has public methods
final publicMethods =
classElement.methods.where((m) => m.isPublic).toList();
final publicMethods = classElement.methods2
.where((m) => m.isPublic)
.toList();
if (publicMethods.isEmpty) {
throw AnnotationValidationException(
'Module class must have at least one public method',
@@ -314,7 +322,9 @@ class AnnotationValidator {
// Validate that public methods have appropriate annotations
for (final method in publicMethods) {
final methodAnnotations = _getAnnotationNames(method.metadata);
final methodAnnotations = _getAnnotationNames(
method.firstFragment.metadata2.annotations,
);
if (!methodAnnotations.contains('instance') &&
!methodAnnotations.contains('provide')) {
throw AnnotationValidationException(
@@ -332,7 +342,7 @@ class AnnotationValidator {
/// Checks @injectable usage on classes and their fields.
static void _validateInjectableClassAnnotations(
ClassElement classElement,
ClassElement2 classElement,
List<String> annotations,
) {
if (!annotations.contains('injectable')) {
@@ -340,8 +350,10 @@ class AnnotationValidator {
}
// Check if class has injectable fields
final injectFields = classElement.fields.where((f) {
final fieldAnnotations = _getAnnotationNames(f.metadata);
final injectFields = classElement.fields2.where((f) {
final fieldAnnotations = _getAnnotationNames(
f.firstFragment.metadata2.annotations,
);
return fieldAnnotations.contains('inject');
}).toList();

View File

@@ -11,7 +11,7 @@
// limitations under the License.
//
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'bind_parameters_spec.dart';
import 'metadata_utils.dart';
@@ -25,7 +25,7 @@ enum BindingType {
instance,
/// Provider/factory function (@provide).
provide;
provide,
}
/// ---------------------------------------------------------------------------
@@ -155,7 +155,8 @@ class BindSpec {
switch (bindingType) {
case BindingType.instance:
throw StateError(
'Internal error: _generateWithParamsProvideClause called for @instance binding with @params.');
'Internal error: _generateWithParamsProvideClause called for @instance binding with @params.',
);
//return isAsyncInstance
// ? '.toInstanceAsync(($fnArgs) => $methodName($fnArgs))'
// : '.toInstance(($fnArgs) => $methodName($fnArgs))';
@@ -189,20 +190,24 @@ class BindSpec {
case BindingType.provide:
if (isAsyncProvide) {
if (needsMultiline) {
final lambdaIndent =
(isSingleton || named != null) ? indent + 6 : indent + 2;
final closingIndent =
(isSingleton || named != null) ? indent + 4 : indent;
final lambdaIndent = (isSingleton || named != null)
? indent + 6
: indent + 2;
final closingIndent = (isSingleton || named != null)
? indent + 4
: indent;
return '.toProvideAsync(\n${' ' * lambdaIndent}() => $methodName($argsStr),\n${' ' * closingIndent})';
} else {
return '.toProvideAsync(() => $methodName($argsStr))';
}
} else {
if (needsMultiline) {
final lambdaIndent =
(isSingleton || named != null) ? indent + 6 : indent + 2;
final closingIndent =
(isSingleton || named != null) ? indent + 4 : indent;
final lambdaIndent = (isSingleton || named != null)
? indent + 6
: indent + 2;
final closingIndent = (isSingleton || named != null)
? indent + 4
: indent;
return '.toProvide(\n${' ' * lambdaIndent}() => $methodName($argsStr),\n${' ' * closingIndent})';
} else {
return '.toProvide(() => $methodName($argsStr))';
@@ -246,7 +251,7 @@ class BindSpec {
/// print(bindSpec.returnType); // e.g., 'Logger'
/// ```
/// Throws [AnnotationValidationException] or [CodeGenerationException] if invalid.
static BindSpec fromMethod(MethodElement method) {
static BindSpec fromMethod(MethodElement2 method) {
try {
// Validate method annotations
AnnotationValidator.validateMethodAnnotations(method);
@@ -254,28 +259,44 @@ class BindSpec {
// Parse return type using improved type parser
final parsedReturnType = TypeParser.parseType(method.returnType, method);
final methodName = method.displayName;
final methodName = method.firstFragment.name2 ?? '';
// Check for @singleton annotation.
final isSingleton = MetadataUtils.anyMeta(method.metadata, 'singleton');
final isSingleton = MetadataUtils.anyMeta(
method.firstFragment.metadata2.annotations,
'singleton',
);
// Get @named value if present.
final named = MetadataUtils.getNamedValue(method.metadata);
final named = MetadataUtils.getNamedValue(
method.firstFragment.metadata2.annotations,
);
// Parse each method parameter.
final params = <BindParameterSpec>[];
bool hasParams = false;
for (final p in method.parameters) {
for (final p in method.formalParameters) {
final typeStr = p.type.getDisplayString();
final paramNamed = MetadataUtils.getNamedValue(p.metadata);
final isParams = MetadataUtils.anyMeta(p.metadata, 'params');
final paramNamed = MetadataUtils.getNamedValue(
p.firstFragment.metadata2.annotations,
);
final isParams = MetadataUtils.anyMeta(
p.firstFragment.metadata2.annotations,
'params',
);
if (isParams) hasParams = true;
params.add(BindParameterSpec(typeStr, paramNamed, isParams: isParams));
}
// Determine bindingType: @instance or @provide.
final hasInstance = MetadataUtils.anyMeta(method.metadata, 'instance');
final hasProvide = MetadataUtils.anyMeta(method.metadata, 'provide');
final hasInstance = MetadataUtils.anyMeta(
method.firstFragment.metadata2.annotations,
'instance',
);
final hasProvide = MetadataUtils.anyMeta(
method.firstFragment.metadata2.annotations,
'provide',
);
if (!hasInstance && !hasProvide) {
throw AnnotationValidationException(
@@ -290,8 +311,9 @@ class BindSpec {
);
}
final bindingType =
hasInstance ? BindingType.instance : BindingType.provide;
final bindingType = hasInstance
? BindingType.instance
: BindingType.provide;
// PROHIBIT @params with @instance bindings!
if (bindingType == BindingType.instance && hasParams) {

View File

@@ -11,7 +11,7 @@
// limitations under the License.
//
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:source_gen/source_gen.dart';
/// ---------------------------------------------------------------------------
@@ -48,21 +48,21 @@ class CherryPickGeneratorException extends InvalidGenerationSourceError {
CherryPickGeneratorException(
String message, {
required Element element,
required Element2 element,
required this.category,
this.suggestion,
this.context,
}) : super(
_formatMessage(message, category, suggestion, context, element),
element: element,
);
_formatMessage(message, category, suggestion, context, element),
element: element,
);
static String _formatMessage(
String message,
String category,
String? suggestion,
Map<String, dynamic>? context,
Element element,
Element2 element,
) {
final buffer = StringBuffer();
@@ -74,7 +74,9 @@ class CherryPickGeneratorException extends InvalidGenerationSourceError {
buffer.writeln('Context:');
buffer.writeln(' Element: ${element.displayName}');
buffer.writeln(' Type: ${element.runtimeType}');
buffer.writeln(' Location: ${element.source?.fullName ?? 'unknown'}');
buffer.writeln(
' Location: ${element.firstFragment.libraryFragment?.source.fullName ?? 'unknown'}',
);
// Try to show enclosing element info for extra context
try {

View File

@@ -12,6 +12,7 @@
//
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'bind_spec.dart';
/// ---------------------------------------------------------------------------
@@ -75,14 +76,11 @@ class GeneratedClass {
/// final gen = GeneratedClass.fromClassElement(classElement);
/// print(gen.generatedClassName); // e.g. $AppModule
/// ```
static GeneratedClass fromClassElement(ClassElement element) {
final className = element.displayName;
// Generated class name with '$' prefix (standard for generated Dart code).
static GeneratedClass fromClassElement(ClassElement2 element) {
final className = element.firstFragment.name2 ?? '';
final generatedClassName = r'$' + className;
// Get source file name
final sourceFile = element.source.shortName;
// Collect bindings for all non-abstract methods.
final binds = element.methods
final sourceFile = element.firstFragment.libraryFragment.source.shortName;
final binds = element.methods2
.where((m) => !m.isAbstract)
.map(BindSpec.fromMethod)
.toList();

View File

@@ -41,14 +41,16 @@ class MetadataUtils {
/// bool isSingleton = MetadataUtils.anyMeta(myMethod.metadata, 'singleton');
/// ```
static bool anyMeta(List<ElementAnnotation> meta, String typeName) {
return meta.any((m) =>
m
.computeConstantValue()
?.type
?.getDisplayString()
.toLowerCase()
.contains(typeName.toLowerCase()) ??
false);
return meta.any(
(m) =>
m
.computeConstantValue()
?.type
?.getDisplayString()
.toLowerCase()
.contains(typeName.toLowerCase()) ??
false,
);
}
/// Extracts the string value from a `@named('value')` annotation if present in [meta].

View File

@@ -11,7 +11,7 @@
// limitations under the License.
//
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'exceptions.dart';
@@ -45,7 +45,7 @@ class TypeParser {
/// final parsed = TypeParser.parseType(field.type, field);
/// if (parsed.isNullable) print('Field is nullable');
/// ```
static ParsedType parseType(DartType dartType, Element context) {
static ParsedType parseType(DartType dartType, Element2 context) {
try {
return _parseTypeInternal(dartType, context);
} catch (e) {
@@ -61,7 +61,7 @@ class TypeParser {
}
}
static ParsedType _parseTypeInternal(DartType dartType, Element context) {
static ParsedType _parseTypeInternal(DartType dartType, Element2 context) {
final displayString = dartType.getDisplayString();
final isNullable = dartType.nullabilitySuffix == NullabilitySuffix.question;
@@ -87,7 +87,10 @@ class TypeParser {
}
static ParsedType _parseFutureType(
DartType dartType, Element context, bool isNullable) {
DartType dartType,
Element2 context,
bool isNullable,
) {
if (dartType is! ParameterizedType || dartType.typeArguments.isEmpty) {
throw TypeParsingException(
'Future type must have a type argument',
@@ -112,7 +115,10 @@ class TypeParser {
}
static ParsedType _parseGenericType(
ParameterizedType dartType, Element context, bool isNullable) {
ParameterizedType dartType,
Element2 context,
bool isNullable,
) {
final typeArguments = dartType.typeArguments
.map((arg) => _parseTypeInternal(arg, context))
.toList();
@@ -138,7 +144,7 @@ class TypeParser {
/// final parsed = TypeParser.parseType(field.type, field);
/// TypeParser.validateInjectableType(parsed, field);
/// ```
static void validateInjectableType(ParsedType parsedType, Element context) {
static void validateInjectableType(ParsedType parsedType, Element2 context) {
// Check for void type
if (parsedType.coreType == 'void') {
throw TypeParsingException(

View File

@@ -2,7 +2,7 @@ name: cherrypick_generator
description: |
Source code generator for the cherrypick dependency injection system. Processes annotations to generate binding and module code for Dart & Flutter projects.
version: 3.0.1
version: 3.0.2-dev.0
homepage: https://cherrypick-di.netlify.app
documentation: https://cherrypick-di.netlify.app/docs/intro
repository: https://github.com/pese-git/cherrypick/cherrypick_generator
@@ -15,20 +15,20 @@ topics:
- inversion-of-control
environment:
sdk: ">=3.6.0 <4.0.0"
sdk: ">=3.8.0 <4.0.0"
# Add regular dependencies here.
dependencies:
cherrypick_annotations: ^3.0.1
analyzer: ^7.7.1
cherrypick_annotations: ^3.0.2-dev.0
analyzer: ">=7.5.9 <8.0.0"
dart_style: ^3.0.0
build: ^2.4.1
source_gen: ^2.0.0
build: ^3.0.0
source_gen: ^3.1.0
collection: ^1.18.0
dev_dependencies:
lints: ^5.1.1
lints: ^6.0.0
mockito: ^5.4.5
test: ^1.25.8
build_test: ^2.1.7
build_runner: ^2.4.13
build_test: ^3.0.0
build_runner: ^2.5.0

View File

@@ -480,9 +480,10 @@ void notAClass() {}
);
});
test('should generate empty mixin for class without @inject fields',
() async {
const input = '''
test(
'should generate empty mixin for class without @inject fields',
() async {
const input = '''
import 'package:cherrypick_annotations/cherrypick_annotations.dart';
part 'test_widget.inject.cherrypick.g.dart';
@@ -494,7 +495,7 @@ class TestWidget {
}
''';
const expectedOutput = '''
const expectedOutput = '''
// dart format width=80
// GENERATED CODE - DO NOT MODIFY BY HAND
@@ -509,8 +510,9 @@ mixin _\$TestWidget {
}
''';
await _testGeneration(input, expectedOutput);
});
await _testGeneration(input, expectedOutput);
},
);
});
group('Edge Cases', () {
@@ -593,12 +595,8 @@ mixin _\$TestWidget {
Future<void> _testGeneration(String input, String expectedOutput) async {
await testBuilder(
injectBuilder(BuilderOptions.empty),
{
'a|lib/test_widget.dart': input,
},
outputs: {
'a|lib/test_widget.inject.cherrypick.g.dart': expectedOutput,
},
reader: await PackageAssetReader.currentIsolate(),
{'a|lib/test_widget.dart': input},
outputs: {'a|lib/test_widget.inject.cherrypick.g.dart': expectedOutput},
readerWriter: TestReaderWriter(),
);
}

View File

@@ -590,9 +590,10 @@ void notAClass() {}
);
});
test('should throw error for method without @instance or @provide',
() async {
const input = '''
test(
'should throw error for method without @instance or @provide',
() async {
const input = '''
import 'package:cherrypick_annotations/cherrypick_annotations.dart';
import 'package:cherrypick/cherrypick.dart';
@@ -604,11 +605,12 @@ abstract class TestModule extends Module {
}
''';
await expectLater(
() => _testGeneration(input, ''),
throwsA(isA<InvalidGenerationSourceError>()),
);
});
await expectLater(
() => _testGeneration(input, ''),
throwsA(isA<InvalidGenerationSourceError>()),
);
},
);
test('should throw error for @params with @instance', () async {
const input = '''
@@ -637,12 +639,8 @@ abstract class TestModule extends Module {
Future<void> _testGeneration(String input, String expectedOutput) async {
await testBuilder(
moduleBuilder(BuilderOptions.empty),
{
'a|lib/test_module.dart': input,
},
outputs: {
'a|lib/test_module.module.cherrypick.g.dart': expectedOutput,
},
reader: await PackageAssetReader.currentIsolate(),
{'a|lib/test_module.dart': input},
outputs: {'a|lib/test_module.module.cherrypick.g.dart': expectedOutput},
readerWriter: TestReaderWriter(),
);
}

View File

@@ -1,7 +1,6 @@
import 'package:analyzer/dart/element/element2.dart';
import 'package:test/test.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/source/source.dart';
import 'package:cherrypick_generator/src/type_parser.dart';
import 'package:cherrypick_generator/src/exceptions.dart';
@@ -42,7 +41,9 @@ void main() {
expect(
() => TypeParser.validateInjectableType(
parsedType, _createMockElement()),
parsedType,
_createMockElement(),
),
throwsA(isA<TypeParsingException>()),
);
});
@@ -59,7 +60,9 @@ void main() {
expect(
() => TypeParser.validateInjectableType(
parsedType, _createMockElement()),
parsedType,
_createMockElement(),
),
throwsA(isA<TypeParsingException>()),
);
});
@@ -76,7 +79,9 @@ void main() {
expect(
() => TypeParser.validateInjectableType(
parsedType, _createMockElement()),
parsedType,
_createMockElement(),
),
returnsNormally,
);
});
@@ -159,19 +164,21 @@ void main() {
expect(parsedType.resolveMethodName, equals('resolveAsync'));
});
test('should return correct resolveMethodName for nullable async types',
() {
final parsedType = ParsedType(
displayString: 'Future<String?>',
coreType: 'String',
isNullable: true,
isFuture: true,
isGeneric: false,
typeArguments: [],
);
test(
'should return correct resolveMethodName for nullable async types',
() {
final parsedType = ParsedType(
displayString: 'Future<String?>',
coreType: 'String',
isNullable: true,
isFuture: true,
isGeneric: false,
typeArguments: [],
);
expect(parsedType.resolveMethodName, equals('tryResolveAsync'));
});
expect(parsedType.resolveMethodName, equals('tryResolveAsync'));
},
);
test('should implement equality correctly', () {
final parsedType1 = ParsedType(
@@ -216,19 +223,19 @@ void main() {
}
// Mock element for testing
Element _createMockElement() {
Element2 _createMockElement() {
return _MockElement();
}
class _MockElement implements Element {
class _MockElement implements Element2 {
@override
String get displayName => 'MockElement';
@override
String get name => 'MockElement';
@override
Source? get source => null;
//@override
//String get name => 'MockElement';
//
//@override
//Source? get source => null;
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);

View File

@@ -9,11 +9,7 @@ void main() {
// Создаем модуль, который будет предоставлять UseCase
]);
runApp(
const CherryPickProvider(
child: MyApp(),
),
);
runApp(const CherryPickProvider(child: MyApp()));
}
class MyApp extends StatelessWidget {
@@ -21,10 +17,6 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CherryPickProvider(
child: MaterialApp(
home: MyHomePage(),
),
);
return CherryPickProvider(child: MaterialApp(home: MyHomePage()));
}
}

View File

@@ -11,12 +11,8 @@ class MyHomePage extends StatelessWidget {
Widget build(BuildContext context) {
//_inject(context); // Make sure this function is called in context
return Scaffold(
appBar: AppBar(
title: const Text('Example App'),
),
body: Center(
child: Text(useCase.fetchData()),
),
appBar: AppBar(title: const Text('Example App')),
body: Center(child: Text(useCase.fetchData())),
);
}
}

View File

@@ -45,18 +45,18 @@ packages:
dependency: transitive
description:
name: build
sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0
sha256: ce76b1d48875e3233fde17717c23d1f60a91cc631597e49a400c89b475395b1d
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "3.1.0"
build_config:
dependency: transitive
description:
name: build_config
sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33"
sha256: "4f64382b97504dc2fcdf487d5aae33418e08b4703fc21249e4db6d804a4d0187"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
version: "1.2.0"
build_daemon:
dependency: transitive
description:
@@ -69,26 +69,26 @@ packages:
dependency: transitive
description:
name: build_resolvers
sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0
sha256: d1d57f7807debd7349b4726a19fd32ec8bc177c71ad0febf91a20f84cd2d4b46
url: "https://pub.dev"
source: hosted
version: "2.4.4"
version: "3.0.3"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99"
sha256: b24597fceb695969d47025c958f3837f9f0122e237c6a22cb082a5ac66c3ca30
url: "https://pub.dev"
source: hosted
version: "2.4.15"
version: "2.7.1"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021"
sha256: "066dda7f73d8eb48ba630a55acb50c4a84a2e6b453b1cb4567f581729e794f7b"
url: "https://pub.dev"
source: hosted
version: "8.0.0"
version: "9.3.1"
built_collection:
dependency: transitive
description:
@@ -117,10 +117,10 @@ packages:
dependency: transitive
description:
name: checked_yaml
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
url: "https://pub.dev"
source: hosted
version: "2.0.3"
version: "2.0.4"
cherrypick:
dependency: "direct main"
description:
@@ -201,10 +201,10 @@ packages:
dependency: transitive
description:
name: dart_style
sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac"
sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.1.1"
fake_async:
dependency: transitive
description:
@@ -238,10 +238,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
url: "https://pub.dev"
source: hosted
version: "5.0.0"
version: "6.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -271,14 +271,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.2"
http:
dependency: transitive
description:
name: http
sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
url: "https://pub.dev"
source: hosted
version: "1.5.0"
http_multi_server:
dependency: transitive
description:
@@ -303,14 +295,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.5"
js:
dependency: transitive
description:
name: js
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
url: "https://pub.dev"
source: hosted
version: "0.7.1"
json_annotation:
dependency: transitive
description:
@@ -347,10 +331,10 @@ packages:
dependency: transitive
description:
name: lints
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
url: "https://pub.dev"
source: hosted
version: "5.1.1"
version: "6.0.0"
logging:
dependency: transitive
description:
@@ -456,10 +440,10 @@ packages:
dependency: transitive
description:
name: source_gen
sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b"
sha256: "7b19d6ba131c6eb98bfcbf8d56c1a7002eba438af2e7ae6f8398b2b0f4f381e3"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
version: "3.1.0"
source_span:
dependency: transitive
description:
@@ -589,5 +573,5 @@ packages:
source: hosted
version: "3.1.3"
sdks:
dart: ">=3.7.0-0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"
dart: ">=3.8.0 <4.0.0"
flutter: ">=3.32.0"

View File

@@ -5,7 +5,7 @@ publish_to: 'none'
version: 1.0.0+1
environment:
sdk: ">=3.5.2 <4.0.0"
sdk: ">=3.8.0 <4.0.0"
dependencies:
@@ -25,11 +25,11 @@ dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
flutter_lints: ^6.0.0
cherrypick_generator:
path: ../../cherrypick_generator
build_runner: ^2.4.15
build_runner: ^2.5.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

View File

@@ -4,7 +4,7 @@ part 'post_model.freezed.dart';
part 'post_model.g.dart';
@freezed
class PostModel with _$PostModel {
abstract class PostModel with _$PostModel {
const factory PostModel({
required int id,
required String title,

View File

@@ -12,9 +12,9 @@ class PostRepositoryImpl implements PostRepository {
Future<Either<Exception, List<Post>>> getPosts() async {
try {
final posts = await api.getPosts();
return Right(posts
.map((e) => Post(id: e.id, title: e.title, body: e.body))
.toList());
return Right(
posts.map((e) => Post(id: e.id, title: e.title, body: e.body)).toList(),
);
} catch (e) {
return Left(Exception(e.toString()));
}

View File

@@ -15,16 +15,17 @@ abstract class AppModule extends Module {
@provide()
@singleton()
TalkerDioLoggerSettings talkerDioLoggerSettings() => TalkerDioLoggerSettings(
printRequestHeaders: true,
printResponseHeaders: true,
printResponseMessage: true,
);
printRequestHeaders: true,
printResponseHeaders: true,
printResponseMessage: true,
);
@provide()
@singleton()
TalkerDioLogger talkerDioLogger(
Talker talker, TalkerDioLoggerSettings settings) =>
TalkerDioLogger(talker: talker, settings: settings);
Talker talker,
TalkerDioLoggerSettings settings,
) => TalkerDioLogger(talker: talker, settings: settings);
@instance()
int timeout() => 1000;
@@ -75,12 +76,14 @@ abstract class AppModule extends Module {
@provide()
@named('TestProvideWithParams1')
String testProvideWithParams1(
@named('baseUrl') String baseUrl, @params() dynamic params) =>
"hello $params";
@named('baseUrl') String baseUrl,
@params() dynamic params,
) => "hello $params";
@provide()
@named('TestProvideAsyncWithParams1')
Future<String> testProvideAsyncWithParams1(
@named('baseUrl') String baseUrl, @params() dynamic params) async =>
"hello $params";
@named('baseUrl') String baseUrl,
@params() dynamic params,
) async => "hello $params";
}

View File

@@ -3,7 +3,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'post.freezed.dart';
@freezed
class Post with _$Post {
abstract class Post with _$Post {
const factory Post({
required int id,
required String title,

View File

@@ -23,10 +23,10 @@ void main() {
}
// Используем safe root scope для гарантии защиты
CherryPick.openRootScope()
.installModules([CoreModule(talker: talker), $AppModule()]);
CherryPick.openRootScope().installModules([
CoreModule(talker: talker),
$AppModule(),
]);
runApp(MyApp(
talker: talker,
));
runApp(MyApp(talker: talker));
}

View File

@@ -12,10 +12,7 @@ class PostDetailsPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Post #${post.id}')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(post.body),
),
body: Padding(padding: const EdgeInsets.all(16), child: Text(post.body)),
);
}
}

View File

@@ -38,8 +38,9 @@ class PostsPage extends StatelessWidget {
title: Text(posts[i].title),
subtitle: Text(posts[i].body),
onTap: () {
AutoRouter.of(context)
.push(PostDetailsRoute(post: posts[i]));
AutoRouter.of(
context,
).push(PostDetailsRoute(post: posts[i]));
},
),
),

View File

@@ -5,8 +5,8 @@ import 'app_router.gr.dart';
class AppRouter extends RootStackRouter {
@override
List<AutoRoute> get routes => [
AutoRoute(page: PostsRoute.page, initial: true),
AutoRoute(page: PostDetailsRoute.page),
AutoRoute(page: LogsRoute.page),
];
AutoRoute(page: PostsRoute.page, initial: true),
AutoRoute(page: PostDetailsRoute.page),
AutoRoute(page: LogsRoute.page),
];
}

View File

@@ -53,18 +53,18 @@ packages:
dependency: "direct main"
description:
name: auto_route
sha256: b8c036fa613a98a759cf0fdcba26e62f4985dcbff01a5e760ab411e8554bbaf0
sha256: c820e918863a03544aac68eaf61e17c8a6126b663d7cad24a8fd3657a1e6be61
url: "https://pub.dev"
source: hosted
version: "10.1.0+1"
version: "10.1.2"
auto_route_generator:
dependency: "direct dev"
description:
name: auto_route_generator
sha256: "8e622d26dc6be4bf496d47969e3e9ba555c3abcf2290da6abfa43cbd4f57fa52"
sha256: ed4b65e85b4b2b00b06ef1e44c8623985c52c32d05d72147e3201257aa70a115
url: "https://pub.dev"
source: hosted
version: "10.0.1"
version: "10.2.4"
bloc:
dependency: transitive
description:
@@ -85,18 +85,18 @@ packages:
dependency: transitive
description:
name: build
sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0
sha256: ce76b1d48875e3233fde17717c23d1f60a91cc631597e49a400c89b475395b1d
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "3.1.0"
build_config:
dependency: transitive
description:
name: build_config
sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33"
sha256: "4f64382b97504dc2fcdf487d5aae33418e08b4703fc21249e4db6d804a4d0187"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
version: "1.2.0"
build_daemon:
dependency: transitive
description:
@@ -109,26 +109,26 @@ packages:
dependency: transitive
description:
name: build_resolvers
sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0
sha256: d1d57f7807debd7349b4726a19fd32ec8bc177c71ad0febf91a20f84cd2d4b46
url: "https://pub.dev"
source: hosted
version: "2.4.4"
version: "3.0.3"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99"
sha256: b24597fceb695969d47025c958f3837f9f0122e237c6a22cb082a5ac66c3ca30
url: "https://pub.dev"
source: hosted
version: "2.4.15"
version: "2.7.1"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021"
sha256: "066dda7f73d8eb48ba630a55acb50c4a84a2e6b453b1cb4567f581729e794f7b"
url: "https://pub.dev"
source: hosted
version: "8.0.0"
version: "9.3.1"
built_collection:
dependency: transitive
description:
@@ -165,10 +165,10 @@ packages:
dependency: transitive
description:
name: checked_yaml
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
url: "https://pub.dev"
source: hosted
version: "2.0.3"
version: "2.0.4"
cherrypick:
dependency: "direct main"
description:
@@ -189,15 +189,23 @@ packages:
path: "../../cherrypick_generator"
relative: true
source: path
version: "3.0.1"
version: "3.0.0"
cli_config:
dependency: transitive
description:
name: cli_config
sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
url: "https://pub.dev"
source: hosted
version: "0.2.0"
cli_launcher:
dependency: transitive
description:
name: cli_launcher
sha256: "67d89e0a1c07b103d1253f6b953a43d3f502ee36805c8cfc21196282c9ddf177"
sha256: "17d2744fb9a254c49ec8eda582536abe714ea0131533e24389843a4256f82eac"
url: "https://pub.dev"
source: hosted
version: "0.3.2"
version: "0.3.2+1"
cli_util:
dependency: transitive
description:
@@ -234,10 +242,10 @@ packages:
dependency: transitive
description:
name: conventional_commit
sha256: fad254feb6fb8eace2be18855176b0a4b97e0d50e416ff0fe590d5ba83735d34
sha256: c40b1b449ce2a63fa2ce852f35e3890b1e182f5951819934c0e4a66254bc0dc3
url: "https://pub.dev"
source: hosted
version: "0.6.1"
version: "0.6.1+1"
convert:
dependency: transitive
description:
@@ -246,6 +254,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.2"
coverage:
dependency: transitive
description:
name: coverage
sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d"
url: "https://pub.dev"
source: hosted
version: "1.15.0"
cross_file:
dependency: transitive
description:
@@ -274,10 +290,10 @@ packages:
dependency: transitive
description:
name: dart_style
sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac"
sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.1.1"
dartz:
dependency: "direct main"
description:
@@ -314,10 +330,10 @@ packages:
dependency: transitive
description:
name: ffi
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.4"
file:
dependency: transitive
description:
@@ -351,10 +367,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
url: "https://pub.dev"
source: hosted
version: "5.0.0"
version: "6.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -369,18 +385,18 @@ packages:
dependency: "direct dev"
description:
name: freezed
sha256: "59a584c24b3acdc5250bb856d0d3e9c0b798ed14a4af1ddb7dc1c7b41df91c9c"
sha256: da32f8ba8cfcd4ec71d9decc8cbf28bd2c31b5283d9887eb51eb4a0659d8110c
url: "https://pub.dev"
source: hosted
version: "2.5.8"
version: "3.2.0"
freezed_annotation:
dependency: "direct main"
description:
name: freezed_annotation
sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2
sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8"
url: "https://pub.dev"
source: hosted
version: "2.4.4"
version: "3.1.0"
frontend_server_client:
dependency: transitive
description:
@@ -413,6 +429,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.3.4"
hotreloader:
dependency: transitive
description:
name: hotreloader
sha256: bc167a1163807b03bada490bfe2df25b0d744df359227880220a5cbd04e5734b
url: "https://pub.dev"
source: hosted
version: "4.3.0"
http:
dependency: transitive
description:
@@ -437,14 +461,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.1.2"
intl:
dependency: transitive
description:
name: intl
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
url: "https://pub.dev"
source: hosted
version: "0.19.0"
io:
dependency: transitive
description:
@@ -457,12 +473,12 @@ packages:
dependency: transitive
description:
name: js
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
url: "https://pub.dev"
source: hosted
version: "0.7.1"
version: "0.7.2"
json_annotation:
dependency: transitive
dependency: "direct main"
description:
name: json_annotation
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
@@ -473,10 +489,10 @@ packages:
dependency: "direct dev"
description:
name: json_serializable
sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c
sha256: "33a040668b31b320aafa4822b7b1e177e163fc3c1e835c6750319d4ab23aa6fe"
url: "https://pub.dev"
source: hosted
version: "6.9.5"
version: "6.11.1"
leak_tracker:
dependency: transitive
description:
@@ -501,14 +517,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.1"
lean_builder:
dependency: transitive
description:
name: lean_builder
sha256: "3d3a04c9dda8ced6b2a48d23aaf98ef5aa32f68f9c62da1b6c6d45bf03aa8164"
url: "https://pub.dev"
source: hosted
version: "0.1.1"
lints:
dependency: transitive
description:
name: lints
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
url: "https://pub.dev"
source: hosted
version: "5.1.1"
version: "6.0.0"
logging:
dependency: transitive
description:
@@ -537,10 +561,10 @@ packages:
dependency: "direct dev"
description:
name: melos
sha256: "3f3ab3f902843d1e5a1b1a4dd39a4aca8ba1056f2d32fd8995210fa2843f646f"
sha256: "4280dc46bd5b741887cce1e67e5c1a6aaf3c22310035cf5bd33dceeeda62ed22"
url: "https://pub.dev"
source: hosted
version: "6.3.2"
version: "6.3.3"
meta:
dependency: transitive
description:
@@ -573,6 +597,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.0"
node_preamble:
dependency: transitive
description:
name: node_preamble
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
package_config:
dependency: transitive
description:
@@ -601,18 +633,18 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9
sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db"
url: "https://pub.dev"
source: hosted
version: "2.2.17"
version: "2.2.18"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2"
path_provider_linux:
dependency: transitive
description:
@@ -637,14 +669,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "6.0.2"
platform:
dependency: transitive
description:
@@ -689,10 +713,10 @@ packages:
dependency: transitive
description:
name: protobuf
sha256: "579fe5557eae58e3adca2e999e38f02441d8aa908703854a9e0a0f47fa857731"
sha256: de9c9eb2c33f8e933a42932fe1dc504800ca45ebc3d673e6ed7f39754ee4053e
url: "https://pub.dev"
source: hosted
version: "4.1.0"
version: "4.2.0"
provider:
dependency: transitive
description:
@@ -713,10 +737,10 @@ packages:
dependency: transitive
description:
name: pub_updater
sha256: "54e8dc865349059ebe7f163d6acce7c89eb958b8047e6d6e80ce93b13d7c9e60"
sha256: "739a0161d73a6974c0675b864fb0cf5147305f7b077b7f03a58fa7a9ab3e7e7d"
url: "https://pub.dev"
source: hosted
version: "0.4.0"
version: "0.5.0"
pubspec_parse:
dependency: transitive
description:
@@ -729,18 +753,18 @@ packages:
dependency: "direct main"
description:
name: retrofit
sha256: "84d70114a5b6bae5f4c1302335f9cb610ebeb1b02023d5e7e87697aaff52926a"
sha256: "699cf44ec6c7fc7d248740932eca75d334e36bdafe0a8b3e9ff93100591c8a25"
url: "https://pub.dev"
source: hosted
version: "4.6.0"
version: "4.7.2"
retrofit_generator:
dependency: "direct dev"
description:
name: retrofit_generator
sha256: e48c5a7ac362621b74976c64c540500dc7a54b8b5b074616a96a4854a2e5bb5b
sha256: "4a2ac0364eb7d5975f71450dfd553b1591ecffad96438a01ce88494a266bceb4"
url: "https://pub.dev"
source: hosted
version: "9.6.0"
version: "10.0.5"
share_plus:
dependency: transitive
description:
@@ -765,6 +789,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.2"
shelf_packages_handler:
dependency: transitive
description:
name: shelf_packages_handler
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
shelf_static:
dependency: transitive
description:
name: shelf_static
sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3
url: "https://pub.dev"
source: hosted
version: "1.1.3"
shelf_web_socket:
dependency: transitive
description:
@@ -782,18 +822,34 @@ packages:
dependency: transitive
description:
name: source_gen
sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b"
sha256: "7b19d6ba131c6eb98bfcbf8d56c1a7002eba438af2e7ae6f8398b2b0f4f381e3"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
version: "3.1.0"
source_helper:
dependency: transitive
description:
name: source_helper
sha256: a447acb083d3a5ef17f983dd36201aeea33fedadb3228fa831f2f0c92f0f3aca
sha256: "6a3c6cc82073a8797f8c4dc4572146114a39652851c157db37e964d9c7038723"
url: "https://pub.dev"
source: hosted
version: "1.3.7"
version: "1.3.8"
source_map_stack_trace:
dependency: transitive
description:
name: source_map_stack_trace
sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
url: "https://pub.dev"
source: hosted
version: "2.1.2"
source_maps:
dependency: transitive
description:
name: source_maps
sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812"
url: "https://pub.dev"
source: hosted
version: "0.10.13"
source_span:
dependency: transitive
description:
@@ -897,6 +953,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.2"
test:
dependency: transitive
description:
name: test
sha256: "301b213cd241ca982e9ba50266bd3f5bd1ea33f1455554c5abb85d1be0e2d87e"
url: "https://pub.dev"
source: hosted
version: "1.25.15"
test_api:
dependency: transitive
description:
@@ -905,6 +969,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.4"
test_core:
dependency: transitive
description:
name: test_core
sha256: "84d17c3486c8dfdbe5e12a50c8ae176d15e2a771b96909a9442b40173649ccaa"
url: "https://pub.dev"
source: hosted
version: "0.6.8"
timing:
dependency: transitive
description:
@@ -1009,14 +1081,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.3"
webkit_inspection_protocol:
dependency: transitive
description:
name: webkit_inspection_protocol
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
win32:
dependency: transitive
description:
name: win32
sha256: daf97c9d80197ed7b619040e86c8ab9a9dad285e7671ee7390f9180cc828a51e
sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03"
url: "https://pub.dev"
source: hosted
version: "5.10.1"
version: "5.14.0"
xdg_directories:
dependency: transitive
description:
@@ -1025,14 +1105,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.0"
xml:
xxh3:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
name: xxh3
sha256: "399a0438f5d426785723c99da6b16e136f4953fb1e9db0bf270bd41dd4619916"
url: "https://pub.dev"
source: hosted
version: "6.5.0"
version: "1.2.0"
yaml:
dependency: transitive
description:
@@ -1050,5 +1130,5 @@ packages:
source: hosted
version: "2.2.2"
sdks:
dart: ">=3.7.0-0 <4.0.0"
flutter: ">=3.27.0"
dart: ">=3.8.0 <4.0.0"
flutter: ">=3.32.0"

View File

@@ -5,21 +5,20 @@ publish_to: 'none'
version: 1.0.0+1
environment:
sdk: ">=3.6.0 <4.0.0"
sdk: ">=3.8.0 <4.0.0"
dependencies:
flutter:
sdk: flutter
cherrypick:
path: ../../cherrypick
cherrypick_annotations:
path: ../../cherrypick_annotations
cherrypick: any
cherrypick_annotations: ^3.0.2-dev.0
dio: ^5.4.0
retrofit: ^4.0.3
freezed_annotation: ^2.4.4
freezed_annotation: ^3.0.0
json_annotation: ^4.9.0
dartz: ^0.10.1
flutter_bloc: ^9.1.1
auto_route: ^10.1.0+1
@@ -28,25 +27,23 @@ dependencies:
cupertino_icons: ^1.0.8
talker_flutter: ^5.0.0
talker_cherrypick_logger:
path: ../../talker_cherrypick_logger
talker_cherrypick_logger: any
talker_dio_logger: ^5.0.0
talker_bloc_logger: ^5.0.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
flutter_lints: ^6.0.0
build_runner: 2.4.15
cherrypick_generator:
path: ../../cherrypick_generator
build_runner: ^2.5.0
cherrypick_generator: ^3.0.2-dev.0
json_serializable: ^6.9.0
retrofit_generator: ^9.1.5
retrofit_generator: ^10.0.5
auto_route_generator: ^10.0.1
freezed: ^2.5.8
freezed: ^3.0.0
melos: ^6.3.2
flutter:

View File

@@ -16,7 +16,8 @@ scripts:
clean_all:
run: |
melos clean
melos exec -- rm -rf lib/**.g.dart lib/generated/
melos exec -- rm -rf lib/**.g.dart lib/**/**.g.dart lib/generated/
melos exec -- rm -rf .dart_tool build pubspec_overrides.yaml
description: |
Очищает build артефакты flutter и сгенерированный код во всех пакетах.