mirror of
https://github.com/pese-git/cherrypick.git
synced 2026-03-25 13:01:14 +00:00
Compare commits
9 Commits
cherrypick
...
0651f74472
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0651f74472 | ||
|
|
776f29945a | ||
|
|
49361f2f9e | ||
|
|
4953e917c9 | ||
|
|
1997110d92 | ||
|
|
0e600ca3a2 | ||
|
|
25ae208ea1 | ||
|
|
685c0ae49c | ||
|
|
98d81b13a8 |
58
CHANGELOG.md
58
CHANGELOG.md
@@ -3,6 +3,64 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## 2026-01-29
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`cherrypick_annotations` - `v3.0.2`](#cherrypick_annotations---v302)
|
||||
- [`cherrypick_generator` - `v3.0.2`](#cherrypick_generator---v302)
|
||||
|
||||
Packages graduated to a stable release (see pre-releases prior to the stable version for changelog entries):
|
||||
|
||||
- `cherrypick_annotations` - `v3.0.2`
|
||||
- `cherrypick_generator` - `v3.0.2`
|
||||
|
||||
---
|
||||
|
||||
#### `cherrypick_annotations` - `v3.0.2`
|
||||
|
||||
#### `cherrypick_generator` - `v3.0.2`
|
||||
|
||||
|
||||
## 2025-10-20
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`cherrypick` - `v3.0.2`](#cherrypick---v302)
|
||||
- [`cherrypick_flutter` - `v3.0.2`](#cherrypick_flutter---v302)
|
||||
- [`talker_cherrypick_logger` - `v3.0.2`](#talker_cherrypick_logger---v302)
|
||||
|
||||
Packages with dependency updates only:
|
||||
|
||||
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
|
||||
|
||||
- `cherrypick_flutter` - `v3.0.2`
|
||||
- `talker_cherrypick_logger` - `v3.0.2`
|
||||
|
||||
---
|
||||
|
||||
#### `cherrypick` - `v3.0.2`
|
||||
|
||||
- **FIX**(test): fix warning.
|
||||
- **FIX**(scope): properly clear binding and module references on dispose.
|
||||
|
||||
|
||||
## 2025-09-09
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -47,7 +47,7 @@ packages:
|
||||
path: "../cherrypick"
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.0"
|
||||
version: "3.0.2"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
## 3.0.2
|
||||
|
||||
- **FIX**(test): fix warning.
|
||||
- **FIX**(scope): properly clear binding and module references on dispose.
|
||||
|
||||
## 3.0.1
|
||||
|
||||
- **DOCS**: add Netlify deployment status badge to README files.
|
||||
|
||||
@@ -498,5 +498,10 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
||||
await d.dispose();
|
||||
}
|
||||
_disposables.clear();
|
||||
|
||||
// Clear modules
|
||||
_modulesList.clear();
|
||||
// Clear binding-index
|
||||
_bindingResolvers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: cherrypick
|
||||
description: Cherrypick is a small dependency injection (DI) library for dart/flutter projects.
|
||||
version: 3.0.1
|
||||
version: 3.0.2
|
||||
homepage: https://cherrypick-di.netlify.app
|
||||
documentation: https://cherrypick-di.netlify.app/docs/intro
|
||||
repository: https://github.com/pese-git/cherrypick
|
||||
|
||||
65
cherrypick/test/binding_memory_leak_test.dart
Normal file
65
cherrypick/test/binding_memory_leak_test.dart
Normal file
@@ -0,0 +1,65 @@
|
||||
import 'dart:async';
|
||||
import 'package:cherrypick/cherrypick.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class HeavyService implements Disposable {
|
||||
static int instanceCount = 0;
|
||||
HeavyService() {
|
||||
instanceCount++;
|
||||
print('HeavyService created. Instance count: '
|
||||
'\u001b[32m$instanceCount\u001b[0m');
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
instanceCount--;
|
||||
print('HeavyService disposed. Instance count: '
|
||||
'\u001b[31m$instanceCount\u001b[0m');
|
||||
}
|
||||
|
||||
static final Finalizer<String> _finalizer = Finalizer((msg) {
|
||||
print('GC FINALIZED HeavyService: $msg');
|
||||
});
|
||||
void registerFinalizer() => _finalizer.attach(this, toString(), detach: this);
|
||||
}
|
||||
|
||||
class HeavyModule extends Module {
|
||||
@override
|
||||
void builder(Scope scope) {
|
||||
bind<HeavyService>().toProvide(() => HeavyService());
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
test('Binding memory is cleared after closing and reopening scope', () async {
|
||||
final root = CherryPick.openRootScope();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
print('\nIteration $i -------------------------------');
|
||||
final subScope = root.openSubScope('leak-test-scope');
|
||||
subScope.installModules([HeavyModule()]);
|
||||
final service = subScope.resolve<HeavyService>();
|
||||
expect(service, isNotNull);
|
||||
await root.closeSubScope('leak-test-scope');
|
||||
// Dart GC не сразу удаляет освобождённые объекты, добавляем паузу и вызываем GC.
|
||||
await Future.delayed(const Duration(milliseconds: 200));
|
||||
}
|
||||
|
||||
// Если dispose не вызвался, instanceCount > 0 => утечка.
|
||||
expect(HeavyService.instanceCount, equals(0));
|
||||
});
|
||||
|
||||
test('Service is finalized after scope is closed/cleaned', () async {
|
||||
final root = CherryPick.openRootScope();
|
||||
HeavyService? ref;
|
||||
{
|
||||
final sub = root.openSubScope('s');
|
||||
sub.installModules([HeavyModule()]);
|
||||
ref = sub.resolve<HeavyService>();
|
||||
ref.registerFinalizer();
|
||||
expect(HeavyService.instanceCount, 1);
|
||||
await root.closeSubScope('s');
|
||||
}
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
expect(HeavyService.instanceCount, 0);
|
||||
});
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
## 3.0.2
|
||||
|
||||
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
|
||||
|
||||
## 3.0.2-dev.0
|
||||
|
||||
- **REFACTOR**(generator): migrate cherrypick_generator to analyzer element2 API.
|
||||
|
||||
@@ -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.2-dev.0
|
||||
version: 3.0.2
|
||||
homepage: https://cherrypick-di.netlify.app
|
||||
documentation: https://cherrypick-di.netlify.app/docs/intro
|
||||
repository: https://github.com/pese-git/cherrypick/cherrypick_annotations
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 3.0.2
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 3.0.1
|
||||
|
||||
- **DOCS**: add Netlify deployment status badge to README files.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: cherrypick_flutter
|
||||
description: "Flutter library that allows access to the root scope through the context using `CherryPickProvider`."
|
||||
version: 3.0.1
|
||||
version: 3.0.2
|
||||
homepage: https://cherrypick-di.netlify.app
|
||||
documentation: https://cherrypick-di.netlify.app/docs/intro
|
||||
repository: https://github.com/pese-git/cherrypick
|
||||
@@ -19,7 +19,7 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
cherrypick: ^3.0.1
|
||||
cherrypick: ^3.0.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 3.0.2
|
||||
|
||||
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
|
||||
|
||||
## 3.0.2-dev.0
|
||||
|
||||
- **REFACTOR**(generator): migrate cherrypick_generator to analyzer element2 API.
|
||||
|
||||
@@ -179,10 +179,10 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
|
||||
// Determine nullability for field types like T? or Future<T?>
|
||||
bool isNullable =
|
||||
dartType.nullabilitySuffix == NullabilitySuffix.question ||
|
||||
(dartType is ParameterizedType &&
|
||||
(dartType).typeArguments.any(
|
||||
(t) => t.nullabilitySuffix == NullabilitySuffix.question,
|
||||
));
|
||||
(dartType is ParameterizedType &&
|
||||
(dartType).typeArguments.any(
|
||||
(t) => t.nullabilitySuffix == NullabilitySuffix.question,
|
||||
));
|
||||
|
||||
return _ParsedInjectField(
|
||||
fieldName: field.firstFragment.name2 ?? '',
|
||||
@@ -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}')"
|
||||
|
||||
@@ -305,9 +305,8 @@ class AnnotationValidator {
|
||||
}
|
||||
|
||||
// Check if class has public methods
|
||||
final publicMethods = classElement.methods2
|
||||
.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',
|
||||
|
||||
@@ -190,24 +190,20 @@ 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))';
|
||||
@@ -311,9 +307,8 @@ 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) {
|
||||
|
||||
@@ -53,9 +53,9 @@ class CherryPickGeneratorException extends InvalidGenerationSourceError {
|
||||
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,
|
||||
|
||||
@@ -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.2-dev.0
|
||||
version: 3.0.2
|
||||
homepage: https://cherrypick-di.netlify.app
|
||||
documentation: https://cherrypick-di.netlify.app/docs/intro
|
||||
repository: https://github.com/pese-git/cherrypick/cherrypick_generator
|
||||
@@ -19,7 +19,7 @@ environment:
|
||||
|
||||
# Add regular dependencies here.
|
||||
dependencies:
|
||||
cherrypick_annotations: ^3.0.2-dev.0
|
||||
cherrypick_annotations: ^3.0.2
|
||||
analyzer: ">=7.5.9 <8.0.0"
|
||||
dart_style: ^3.0.0
|
||||
build: ^3.0.0
|
||||
|
||||
@@ -127,28 +127,28 @@ packages:
|
||||
path: "../../cherrypick"
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.0"
|
||||
version: "3.0.2"
|
||||
cherrypick_annotations:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../../cherrypick_annotations"
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.0"
|
||||
version: "3.0.2-dev.0"
|
||||
cherrypick_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../../cherrypick_flutter"
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.0"
|
||||
version: "3.0.2"
|
||||
cherrypick_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
path: "../../cherrypick_generator"
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.0"
|
||||
version: "3.0.2-dev.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -175,21 +175,21 @@ packages:
|
||||
path: "../../cherrypick"
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.0"
|
||||
version: "3.0.2"
|
||||
cherrypick_annotations:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../../cherrypick_annotations"
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.0"
|
||||
version: "3.0.2-dev.0"
|
||||
cherrypick_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
path: "../../cherrypick_generator"
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.0"
|
||||
version: "3.0.2-dev.0"
|
||||
cli_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -920,7 +920,7 @@ packages:
|
||||
path: "../../talker_cherrypick_logger"
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.0"
|
||||
version: "3.0.2"
|
||||
talker_dio_logger:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
@@ -13,7 +13,7 @@ dependencies:
|
||||
sdk: flutter
|
||||
|
||||
cherrypick: any
|
||||
cherrypick_annotations: ^3.0.2-dev.0
|
||||
cherrypick_annotations: ^3.0.2
|
||||
|
||||
dio: ^5.4.0
|
||||
retrofit: ^4.0.3
|
||||
@@ -38,7 +38,7 @@ dev_dependencies:
|
||||
flutter_lints: ^6.0.0
|
||||
|
||||
build_runner: ^2.5.0
|
||||
cherrypick_generator: ^3.0.2-dev.0
|
||||
cherrypick_generator: ^3.0.2
|
||||
|
||||
json_serializable: ^6.9.0
|
||||
retrofit_generator: ^10.0.5
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 3.0.2
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 3.0.1
|
||||
|
||||
- **DOCS**: add Netlify deployment status badge to README files.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: talker_cherrypick_logger
|
||||
description: A Talker logger integration for CherryPick DI to observe and log DI events and errors.
|
||||
version: 3.0.1
|
||||
version: 3.0.2
|
||||
homepage: https://cherrypick-di.netlify.app
|
||||
documentation: https://cherrypick-di.netlify.app/docs/intro
|
||||
repository: https://github.com/pese-git/cherrypick
|
||||
@@ -18,7 +18,7 @@ environment:
|
||||
# Add regular dependencies here.
|
||||
dependencies:
|
||||
talker: ^5.0.0
|
||||
cherrypick: ^3.0.1
|
||||
cherrypick: ^3.0.2
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
Reference in New Issue
Block a user