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),
          ),
        ),
      ]),
  );
}