reference method

Reference reference(
  1. bool serverCode, {
  2. bool? nullable,
  3. List<String> subDirParts = const [],
  4. required GeneratorConfig config,
  5. String? typeSuffix,
})

Generate a Reference from this definition.

For classes this will be a TypeReference, while records return a RecordType.

Implementation

Reference reference(
  bool serverCode, {
  bool? nullable,
  List<String> subDirParts = const [],
  required GeneratorConfig config,
  String? typeSuffix,
}) {
  if (isRecordType) {
    return code_builder.RecordType((b) {
      b.positionalFieldTypes.addAll([
        for (final f in positionalRecordFields)
          f.reference(
            serverCode,
            subDirParts: subDirParts,
            config: config,
          ),
      ]);

      b.namedFieldTypes.addAll({
        for (final namedField in namedRecordFields)
          namedField.recordFieldName!: namedField.reference(
            serverCode,
            subDirParts: subDirParts,
            config: config,
          ),
      });

      b.isNullable = nullable ?? this.nullable;
    });
  }
  assert(dartType is! RecordType);

  return TypeReference(
    (t) {
      if (url?.startsWith('${_moduleRef}serverpod') ?? false) {
        // module:serverpod reference
        t.url = serverpodUrl(serverCode);
      } else if (url?.startsWith(_moduleRef) ?? false) {
        // module:nickname: reference
        var moduleName = url?.substring(_moduleRef.length);
        var module = config.modules.cast<ModuleConfig?>().firstWhere(
          (m) => m?.nickname == moduleName,
          orElse: () => null,
        );
        if (module == null) {
          throw FormatException(
            'Module with nickname $moduleName not found in config!',
          );
        }
        var packageName = serverCode
            ? module.serverPackage
            : module.dartClientPackage;
        t.url = 'package:$packageName/$packageName.dart';
      } else if (url == 'serverpod' ||
          (className == 'UuidValue' &&
              [
                'serverpod',
                'package:uuid/uuid_value.dart',
                'package:uuid/uuid.dart',
              ].contains(url)) ||
          (url == null &&
              (['UuidValue', ...vectorClassNames]).contains(className))) {
        // serverpod: reference
        t.url = serverpodUrl(serverCode);
      } else if (url?.startsWith('project:') ?? false) {
        // project:path:reference
        var split = url!.split(':');
        t.url =
            'package:'
            '${serverCode ? config.serverPackage : config.dartClientPackage}'
            '/${split[1]}';
      } else if (url == defaultModuleAlias) {
        // protocol: reference
        var localProjectModelDefinition = projectModelDefinition;
        String reference = switch (localProjectModelDefinition) {
          // Import model directly
          SerializableModelDefinition modelDefinition => getRef(
            modelDefinition,
          ),
          // Import model through generated protocol file
          null => 'protocol.dart',
        };

        t.url = p.posix.joinAll([...subDirParts.map((e) => '..'), reference]);
      } else if (!serverCode &&
          (url?.startsWith('package:${config.serverPackage}') ?? false)) {
        // import from the server package
        t.url = url
            ?.replaceFirst(
              'package:${config.serverPackage}',
              'package:${config.dartClientPackage}',
            )
            .replaceFirst('src/generated/', 'src/protocol/');
      } else if (config.modules.any(
        (m) => url?.startsWith('package:${m.serverPackage}') ?? false,
      )) {
        // endpoint definition references from an module
        var module = config.modules.firstWhere(
          (m) => url?.startsWith('package:${m.serverPackage}') ?? false,
        );
        var packageName = serverCode
            ? module.serverPackage
            : module.dartClientPackage;
        t.url = url!.contains('/src/generated/')
            ? 'package:$packageName/$packageName.dart'
            : serverCode
            ? url
            : url?.replaceFirst(
                'package:${module.serverPackage}',
                'package:${module.dartClientPackage}',
              );
      } else {
        t.url = url;
      }
      t.isNullable = nullable ?? this.nullable;
      t.symbol = typeSuffix != null ? '$className$typeSuffix' : className;
      t.types.addAll(
        generics.map(
          (e) => e.reference(
            serverCode,
            subDirParts: subDirParts,
            config: config,
          ),
        ),
      );
    },
  );
}