generate method

Library generate()

Implementation

Library generate() {
  // all environment keys used
  final environments = <String>{};
  // all register modules
  final modules = <ModuleConfig>{};
  for (final dep in dependencies) {
    environments.addAll(dep.environments);
    if (dep.moduleConfig != null) {
      modules.add(dep.moduleConfig!);
    }
  }

  var scopedDeps =
      groupBy<DependencyConfig, String?>(dependencies, (d) => d.scope);
  final scopedBeforeExternalModules = groupBy<ExternalModuleConfig, String?>(
      microPackagesModulesBefore, (d) => d.scope);
  final scopedAfterExternalModules = groupBy<ExternalModuleConfig, String?>(
      microPackagesModulesAfter, (d) => d.scope);

  final isMicroPackage = microPackageName != null;

  throwIf(
    isMicroPackage && scopedDeps.length > 1,
    'Scopes are not supported in micro package modules!',
  );

  // make sure root scope is always generated even if empty
  if (!scopedDeps.containsKey(null)) {
    scopedDeps = {null: const [], ...scopedDeps};
  }
  final allScopeKeys = {
    ...scopedDeps.keys,
    ...scopedBeforeExternalModules.keys,
    ...scopedAfterExternalModules.keys,
  };
  final initMethods = <Method>[];
  for (final scope in allScopeKeys) {
    final scopeDeps = scopedDeps[scope];
    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(),
    );
  }

  return Library(
    (b) => b
      ..comments.addAll([
        'ignore_for_file: type=lint',
        'coverage:ignore-file',
      ])
      ..body.addAll(
        [
          ...environments.map(
            (env) => Field(
              (b) => b
                ..name = '_$env'
                ..type = refer('String')
                ..assignment = literalString(env).code
                ..modifier = FieldModifier.constant,
            ),
          ),
          if (!isMicroPackage) ...[
            if (asExtension)
              Extension(
                (b) => b
                  ..name = 'GetItInjectableX'
                  ..on = _getItRefer
                  ..methods.addAll(initMethods),
              )
            else
              ...initMethods,
          ],

          if (isMicroPackage)
            Class(
              (b) => b
                ..name = '${capitalize(microPackageName!)}PackageModule'
                ..extend = refer(
                  'MicroPackageModule',
                  _injectableImport,
                )
                ..methods.add(initMethods.first),
            ),

          // build modules
          ...modules.map(
            (module) => _buildModule(
              module,
              dependencies.where((e) => e.moduleConfig == module),
            ),
          )
        ],
      ),
  );
}