generate method

Method generate()

Implementation

Method generate() {
  // if true use an awaited initializer
  final useAsyncModifier =
      microPackagesModulesBefore.isNotEmpty ||
      microPackagesModulesAfter.isNotEmpty ||
      hasPreResolvedDependencies(dependencies);

  // all register modules
  final modules = <ModuleConfig>{};
  for (var dep in dependencies) {
    if (dep.moduleConfig != null) {
      modules.add(dep.moduleConfig!);
    }
  }

  final getInstanceRefer = refer(asExtension ? 'this' : 'getIt');

  final ghStatements = [
    for (final pckModule in microPackagesModulesBefore.map((e) => e.module))
      refer(
            pckModule.name,
            pckModule.import,
          )
          .newInstance(const [])
          .property('init')
          .call([_ghLocalRefer])
          .awaited
          .statement,
    ...modules.map(
      (module) => declareFinal(toCamelCase(module.type.name))
          .assign(
            refer('_\$${module.type.name}').call([
              if (moduleHasOverrides(
                allDependencies.where((e) => e.moduleConfig == module),
              ))
                getInstanceRefer,
            ]),
          )
          .statement,
    ),
    ...dependencies.map((dep) {
      if (dep.injectableType == InjectableType.singleton) {
        return buildSingletonRegisterFun(dep);
      } else {
        return buildLazyRegisterFun(dep);
      }
    }),
    for (final pckModule in microPackagesModulesAfter.map((e) => e.module))
      refer(
            pckModule.name,
            pckModule.import,
          )
          .newInstance(const [])
          .property('init')
          .call([_ghLocalRefer])
          .awaited
          .statement,
  ];

  final Reference returnRefer;
  if (isMicroPackage) {
    returnRefer = TypeReference(
      (b) => b
        ..symbol = 'FutureOr'
        ..url = 'dart:async'
        ..types.add(refer('void')),
    );
  } else {
    returnRefer = useAsyncModifier
        ? TypeReference(
            (b) => b
              ..symbol = 'Future'
              ..types.add(_getItRefer),
          )
        : _getItRefer;
  }

  final ghBuilder = refer('GetItHelper', _injectableImport).newInstance(
    [
      getInstanceRefer,
      refer('environment'),
      refer('environmentFilter'),
    ],
  );

  return Method(
    (b) => b
      ..docs.add(
        '\n// initializes the registration of ${scopeName ?? 'main'}-scope dependencies inside of GetIt',
      )
      ..modifier = useAsyncModifier ? MethodModifier.async : null
      ..returns = returnRefer
      ..name = initializerName
      ..annotations.addAll([if (isMicroPackage) refer('override')])
      ..requiredParameters.addAll([
        if (!asExtension && !isMicroPackage)
          Parameter(
            (b) => b
              ..name = 'getIt'
              ..type = _getItRefer,
          ),
        if (isMicroPackage)
          Parameter(
            (b) => b
              ..name = 'gh'
              ..type = _ghRefer,
          ),
      ])
      ..optionalParameters.addAll([
        if (scopeName == null && !isMicroPackage) ...[
          Parameter(
            (b) => b
              ..named = true
              ..name = 'environment'
              ..type = nullableRefer(
                'String',
                nullable: true,
              ),
          ),
          Parameter(
            (b) => b
              ..named = true
              ..name = 'environmentFilter'
              ..type = nullableRefer(
                'EnvironmentFilter',
                url: _injectableImport,
                nullable: true,
              ),
          ),
          if (usesConstructorCallback)
            Parameter(
              (b) => b
                ..named = true
                ..name = 'constructorCallback'
                ..type = nullableRefer(
                  'T Function<T>(T)',
                  nullable: true,
                ),
            ),
        ] else if (!isMicroPackage)
          Parameter(
            (b) => b
              ..named = true
              ..name = 'dispose'
              ..type = nullableRefer(
                'ScopeDisposeFunc',
                url: _getItImport,
                nullable: true,
              ),
          ),
      ])
      ..body = Block(
        (b) => b.statements.addAll([
          if (scopeName != null)
            _ghRefer
                .newInstance([getInstanceRefer])
                .property('initScope${useAsyncModifier ? 'Async' : ''}')
                .call(
                  [literalString(scopeName!)],
                  {
                    'dispose': refer('dispose'),
                    'init': Method(
                      (b) => b
                        ..modifier = useAsyncModifier
                            ? MethodModifier.async
                            : null
                        ..requiredParameters.add(
                          Parameter(
                            (b) => b
                              ..name = 'gh'
                              ..type = refer(
                                'GetItHelper',
                                _injectableImport,
                              ),
                          ),
                        )
                        ..body = Block(
                          (b) => b.statements.addAll(ghStatements),
                        ),
                    ).closure,
                  },
                )
                .returned
                .statement
          else ...[
            if (!isMicroPackage)
              if (dependencies.isNotEmpty ||
                  microPackagesModulesAfter.isNotEmpty ||
                  microPackagesModulesBefore.isNotEmpty)
                declareFinal('gh').assign(ghBuilder).statement
              else
                ghBuilder.statement,
            if (usesConstructorCallback)
              declareFinal('ccb')
                  .assign(
                    refer(
                      'constructorCallback',
                    ).ifNullThen(CodeExpression(Code('<T>(_) => _'))),
                  )
                  .statement,
            ...ghStatements,
            if (!isMicroPackage) getInstanceRefer.returned.statement,
          ],
        ]),
      ),
  );
}