diff --git a/injectable/CHANGELOG.md b/injectable/CHANGELOG.md index bffb82c..d1af542 100644 --- a/injectable/CHANGELOG.md +++ b/injectable/CHANGELOG.md @@ -1,4 +1,6 @@ # ChangeLog +## [2.3.2] +- Add option to pass instance callback function to the init function by @Adam-Langley ## [2.3.1] - Fix PreResolved singletons/factories fail checking environment filters #398 ## [2.3.0] diff --git a/injectable/lib/src/injectable_annotations.dart b/injectable/lib/src/injectable_annotations.dart index 2bebf66..1ce1dde 100644 --- a/injectable/lib/src/injectable_annotations.dart +++ b/injectable/lib/src/injectable_annotations.dart @@ -74,12 +74,12 @@ class InjectableInit { /// feature flag to activate a 'constructor callback'. /// Setting this to 'true' will generate an additional parameter - /// to '$initGetIt' - named "constructorCallback" - a function of signature + /// to '$initGetIt' - named "constructorCallback" - a function of signature /// "T constructorCallback(T)". /// Injectable will pass all injectable objects to this delegate at the /// time of their constructor/module-method invocation. /// defaults to false - final bool usesConstructorCallback; + final bool usesConstructorCallback; /// default constructor const InjectableInit({ diff --git a/injectable/pubspec.yaml b/injectable/pubspec.yaml index 58cdaaf..a524189 100644 --- a/injectable/pubspec.yaml +++ b/injectable/pubspec.yaml @@ -1,6 +1,6 @@ name: injectable description: Injectable is a convenient code generator for get_it. Inspired by Angular DI, Guice DI and inject.dart. -version: 2.3.1 +version: 2.3.2 homepage: https://github.com/Milad-Akarie/injectable environment: diff --git a/injectable_generator/CHANGELOG.md b/injectable_generator/CHANGELOG.md index a73b721..b2c7c66 100644 --- a/injectable_generator/CHANGELOG.md +++ b/injectable_generator/CHANGELOG.md @@ -1,4 +1,6 @@ # ChangeLog +## [2.4.1] +- Add option to pass instance callback function to the init function by @Adam-Langley ## [2.4.0] - Added [rootDir] support for specifying the root directory for the generation process. ## [2.3.0] diff --git a/injectable_generator/lib/code_builder/library_builder.dart b/injectable_generator/lib/code_builder/library_builder.dart index 26168ca..3a7b3d1 100644 --- a/injectable_generator/lib/code_builder/library_builder.dart +++ b/injectable_generator/lib/code_builder/library_builder.dart @@ -145,20 +145,21 @@ class LibraryGenerator with SharedGeneratorCode { final isRootScope = scope == null; initMethods.add( InitMethodGenerator( - scopeDependencies: scopeDeps ?? [], - targetFile: targetFile, - allDependencies: dependencies, - initializerName: - isRootScope ? initializerName : 'init${capitalize(scope)}Scope', - asExtension: asExtension, - scopeName: scope, - isMicroPackage: isMicroPackage, - microPackagesModulesBefore: - scopedBeforeExternalModules[scope]?.toSet() ?? const {}, - microPackagesModulesAfter: - scopedAfterExternalModules[scope]?.toSet() ?? const {}, - usesConstructorCallback: usesConstructorCallback - ).generate(), + scopeDependencies: scopeDeps ?? [], + targetFile: targetFile, + allDependencies: dependencies, + initializerName: isRootScope + ? initializerName + : 'init${capitalize(scope)}Scope', + asExtension: asExtension, + scopeName: scope, + isMicroPackage: isMicroPackage, + microPackagesModulesBefore: + scopedBeforeExternalModules[scope]?.toSet() ?? const {}, + microPackagesModulesAfter: + scopedAfterExternalModules[scope]?.toSet() ?? const {}, + usesConstructorCallback: usesConstructorCallback) + .generate(), ); } @@ -399,14 +400,14 @@ class InitMethodGenerator with SharedGeneratorCode { url: _injectableImport, nullable: true, )), - if (usesConstructorCallback) - Parameter((b) => b - ..named = true - ..name = 'constructorCallback' - ..type = nullableRefer( - 'T Function(T)', - nullable: true, - )), + if (usesConstructorCallback) + Parameter((b) => b + ..named = true + ..name = 'constructorCallback' + ..type = nullableRefer( + 'T Function(T)', + nullable: true, + )), ] else if (!isMicroPackage) Parameter((b) => b ..named = true @@ -450,7 +451,12 @@ class InitMethodGenerator with SharedGeneratorCode { else ghBuilder.statement, if (usesConstructorCallback) - declareFinal('ccb').assign(refer('constructorCallback').ifNullThen(CodeExpression(Code('(_) => _'))),).statement, + declareFinal('ccb') + .assign( + refer('constructorCallback') + .ifNullThen(CodeExpression(Code('(_) => _'))), + ) + .statement, ...ghStatements, if (!isMicroPackage) getInstanceRefer.returned.statement, ], @@ -514,7 +520,7 @@ class InitMethodGenerator with SharedGeneratorCode { Code _buildInstanceBuilderCode( Expression instanceBuilder, DependencyConfig dep) { - if (usesConstructorCallback){ + if (usesConstructorCallback) { instanceBuilder = refer('ccb').call([instanceBuilder]); } var instanceBuilderCode = instanceBuilder.code; diff --git a/injectable_generator/lib/generators/injectable_config_generator.dart b/injectable_generator/lib/generators/injectable_config_generator.dart index 93706c6..a2a2b86 100644 --- a/injectable_generator/lib/generators/injectable_config_generator.dart +++ b/injectable_generator/lib/generators/injectable_config_generator.dart @@ -22,21 +22,31 @@ import 'package:injectable_generator/utils.dart'; class InjectableConfigGenerator extends GeneratorForAnnotation { @override - dynamic generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep) async { - final generateForDir = annotation.read('generateForDir').listValue.map((e) => e.toStringValue()); + dynamic generateForAnnotatedElement( + Element element, ConstantReader annotation, BuildStep buildStep) async { + final generateForDir = annotation + .read('generateForDir') + .listValue + .map((e) => e.toStringValue()); final usesNullSafety = annotation.read('usesNullSafety').boolValue; final isMicroPackage = annotation.read('_isMicroPackage').boolValue; - final usesConstructorCallback = annotation.read('usesConstructorCallback').boolValue; - final throwOnMissingDependencies = annotation.read('throwOnMissingDependencies').boolValue; + final usesConstructorCallback = + annotation.read('usesConstructorCallback').boolValue; + final throwOnMissingDependencies = + annotation.read('throwOnMissingDependencies').boolValue; final targetFile = element.source?.uri; - final preferRelativeImports = annotation.read("preferRelativeImports").boolValue; + final preferRelativeImports = + annotation.read("preferRelativeImports").boolValue; - final includeMicroPackages = annotation.read("includeMicroPackages").boolValue; + final includeMicroPackages = + annotation.read("includeMicroPackages").boolValue; final rootDir = annotation.peek('rootDir')?.stringValue; - final dirPattern = generateForDir.length > 1 ? '{${generateForDir.join(',')}}' : '${generateForDir.first}'; + final dirPattern = generateForDir.length > 1 + ? '{${generateForDir.join(',')}}' + : '${generateForDir.first}'; final injectableConfigFiles = Glob("$dirPattern/**.injectable.json"); @@ -54,11 +64,13 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { final initializerName = annotation.read('initializerName').stringValue; final asExtension = annotation.read('asExtension').boolValue; - final typeResolver = ImportableTypeResolverImpl(await buildStep.resolver.libraries.toList()); + final typeResolver = + ImportableTypeResolverImpl(await buildStep.resolver.libraries.toList()); - final ignoredTypes = annotation.read('ignoreUnregisteredTypes').listValue.map( - (e) => typeResolver.resolveType(e.toTypeValue()!), - ); + final ignoredTypes = + annotation.read('ignoreUnregisteredTypes').listValue.map( + (e) => typeResolver.resolveType(e.toTypeValue()!), + ); final microPackageModulesBefore = _getMicroPackageModules( annotation.peek('externalPackageModulesBefore'), @@ -80,7 +92,8 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { typeResolver, ); - final microPackagesModules = microPackageModulesBefore.union(microPackageModulesAfter); + final microPackagesModules = + microPackageModulesBefore.union(microPackageModulesAfter); if (!isMicroPackage && includeMicroPackages) { final glob = Glob('**.module.dart', recursive: true); final filesStream = glob.list(root: rootDir); @@ -96,7 +109,8 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { import: segments[2], ), ); - if (!microPackagesModules.any((e) => externalModule.module == e.module)) { + if (!microPackagesModules + .any((e) => externalModule.module == e.module)) { microPackageModulesBefore.add(externalModule); } } @@ -115,7 +129,8 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { // we want to ignore unregistered types in microPackages // because the micro module should handle them for (final pckModule in microPackagesModules) { - final packageName = Uri.parse(pckModule.module.import!).pathSegments.first; + final packageName = + Uri.parse(pckModule.module.import!).pathSegments.first; ignoreTypesInPackages.add(packageName); } @@ -144,7 +159,8 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { targetFile: preferRelativeImports ? targetFile : null, initializerName: initializerName, asExtension: asExtension, - microPackageName: isMicroPackage ? buildStep.inputId.package.pascalCase : null, + microPackageName: + isMicroPackage ? buildStep.inputId.package.pascalCase : null, microPackagesModulesBefore: microPackageModulesBefore, microPackagesModulesAfter: microPackageModulesAfter, usesConstructorCallback: usesConstructorCallback, @@ -157,7 +173,8 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { useNullSafetySyntax: usesNullSafety, ); - final output = DartFormatter().format(generatedLib.accept(emitter).toString()); + final output = + DartFormatter().format(generatedLib.accept(emitter).toString()); if (isMicroPackage) { final outputId = buildStep.inputId.changeExtension('.module.dart'); @@ -184,10 +201,12 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { final scope = reader.peek('scope')?.stringValue; throwIf( typeValue.element is! ClassElement || - !TypeChecker.fromRuntime(MicroPackageModule).isSuperOf(typeValue.element!), + !TypeChecker.fromRuntime(MicroPackageModule) + .isSuperOf(typeValue.element!), 'ExternalPackageModule must be a class that extends MicroPackageModule', ); - return ExternalModuleConfig(typeResolver.resolveType(typeValue), scope); + return ExternalModuleConfig( + typeResolver.resolveType(typeValue), scope); }, ).toSet() ?? {}; @@ -202,7 +221,8 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { final typeValue = e.toTypeValue()!; throwIf( typeValue.element is! ClassElement || - !TypeChecker.fromRuntime(MicroPackageModule).isSuperOf(typeValue.element!), + !TypeChecker.fromRuntime(MicroPackageModule) + .isSuperOf(typeValue.element!), 'ExternalPackageModule must be a class that extends MicroPackageModule', ); return ExternalModuleConfig(typeResolver.resolveType(typeValue)); @@ -220,7 +240,8 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { ) { final messages = []; for (final dep in deps) { - for (var iDep in dep.dependencies.where((d) => !d.isFactoryParam && d.instanceName != kEnvironmentsName)) { + for (var iDep in dep.dependencies.where( + (d) => !d.isFactoryParam && d.instanceName != kEnvironmentsName)) { if ((ignoredTypes.contains(iDep.type) || (iDep.type.import == null || ignoredTypesInPackages.any( @@ -235,9 +256,13 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { messages.add( "[${dep.typeImpl}] depends on unregistered type [${iDep.type}] ${iDep.type.import == null ? '' : 'from ${iDep.type.import}'}"); } else { - final availableEnvs = possibleDeps.map((e) => e.environments).reduce((a, b) => a + b).toSet(); + final availableEnvs = possibleDeps + .map((e) => e.environments) + .reduce((a, b) => a + b) + .toSet(); if (availableEnvs.isNotEmpty) { - final missingEnvs = dep.environments.toSet().difference(availableEnvs); + final missingEnvs = + dep.environments.toSet().difference(availableEnvs); if (missingEnvs.isNotEmpty) { messages.add( '[${dep.typeImpl}] ${dep.environments.toSet()} depends on Type [${iDep.type}] ${iDep.type.import == null ? '' : 'from ${iDep.type.import}'} \n which is not available under environment keys $missingEnvs', @@ -252,7 +277,8 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { messages.add( '\nDid you forget to annotate the above class(s) or their implementation with @injectable? \nor add the right environment keys?'); throwIf(throwOnMissingDependencies, messages.join('\n')); - printBoxed(messages.join('\n'), header: "Missing dependencies in ${targetFile?.path}\n"); + printBoxed(messages.join('\n'), + header: "Missing dependencies in ${targetFile?.path}\n"); } } @@ -260,15 +286,21 @@ class InjectableConfigGenerator extends GeneratorForAnnotation { final validatedDeps = []; for (var dep in deps) { var registered = validatedDeps.where( - (elm) => elm.type == dep.type && elm.instanceName == dep.instanceName && elm.scope == dep.scope, + (elm) => + elm.type == dep.type && + elm.instanceName == dep.instanceName && + elm.scope == dep.scope, ); if (registered.isEmpty) { validatedDeps.add(dep); } else { - Set registeredEnvironments = registered.fold({}, (prev, elm) => prev..addAll(elm.environments)); + Set registeredEnvironments = registered + .fold({}, (prev, elm) => prev..addAll(elm.environments)); - if (registeredEnvironments.isEmpty || dep.environments.any((env) => registeredEnvironments.contains(env))) { + if (registeredEnvironments.isEmpty || + dep.environments + .any((env) => registeredEnvironments.contains(env))) { throwBoxed( '${dep.typeImpl} [${dep.type}] envs: ${dep.environments} scope: ${dep.scope} \nis registered more than once under the same environment or in the same scope', ); diff --git a/injectable_generator/pubspec.lock b/injectable_generator/pubspec.lock index c50b918..2819d7c 100644 --- a/injectable_generator/pubspec.lock +++ b/injectable_generator/pubspec.lock @@ -252,10 +252,11 @@ packages: injectable: dependency: "direct main" description: - path: "../injectable" - relative: true - source: path - version: "2.3.0" + name: injectable + sha256: cd3c422e13270c81f64ab73c80406b2b2ed563fe59d0ff2093eb7eee63d0bbeb + url: "https://pub.dev" + source: hosted + version: "2.3.2" io: dependency: transitive description: diff --git a/injectable_generator/pubspec.yaml b/injectable_generator/pubspec.yaml index 7dbc019..49dc0f5 100644 --- a/injectable_generator/pubspec.yaml +++ b/injectable_generator/pubspec.yaml @@ -1,6 +1,6 @@ name: injectable_generator description: Injectable is a convenient code generator for get_it. Inspired by Angular DI, Guice DI and inject.dart. -version: 2.4.0 +version: 2.4.1 homepage: https://github.com/Milad-Akarie/injectable environment: @@ -15,8 +15,8 @@ dependencies: code_builder: ^4.4.0 dart_style: ^2.0.3 injectable: -# ^2.3.0 - path: ../injectable + ^2.3.2 +# path: ../injectable collection: ^1.17.1 recase: ^4.1.0 meta: ^1.9.1