generateConstructor method

void generateConstructor(
  1. BuildContext ctx,
  2. ClassBuilder clazz,
  3. LibraryBuilder file
)

Generate a constructor with named parameters.

Implementation

void generateConstructor(
    BuildContext ctx, ClassBuilder clazz, LibraryBuilder file) {
  clazz.constructors.add(Constructor((constructor) {
    // Add all `super` params
    //constructor.constant = (ctx.clazz.unnamedConstructor?.isConst == true ||
    //        shouldBeConstant(ctx)) &&
    //    ctx.fields.every((f) {
    //      return f.setter == null && f is! ShimFieldImpl;
    //    });

    for (var param in ctx.constructorParameters) {
      //log.fine('Contructor Parameter: ${param.name}');
      constructor.requiredParameters.add(Parameter((b) => b
        ..name = param.name
        ..type = convertTypeReference(param.type)));
    }

    // Generate intializers
    for (var field in ctx.fields) {
      if (!shouldBeConstant(ctx) && isListOrMapType(field.type)) {
        var typeName = const TypeChecker.fromRuntime(List)
                .isAssignableFromType(field.type)
            ? 'List'
            : 'Map';
        String? defaultValue = typeName == 'List' ? '[]' : '{}';

        var existingDefault = ctx.defaults[field.name];
        if (existingDefault != null) {
          defaultValue = dartObjectToString(existingDefault);
        }

        if (field.type.nullabilitySuffix != NullabilitySuffix.question) {
          constructor.initializers.add(Code('''
            ${field.name} =
              $typeName.unmodifiable(${field.name})'''));
        } else {
          constructor.initializers.add(Code('''
            ${field.name} =
              $typeName.unmodifiable(${field.name} ?? $defaultValue)'''));
        }
      }
    }

    // Generate the parameters for the constructor
    for (var field in ctx.fields) {
      //log.fine('Contructor Field: ${field.name}');

      constructor.optionalParameters.add(Parameter((b) {
        b
          ..toThis = shouldBeConstant(ctx)
          ..name = field.name
          ..named = true;

        var existingDefault = ctx.defaults[field.name];

        if (existingDefault != null) {
          var d = dartObjectToString(existingDefault);
          if (d != null) {
            b.defaultTo = Code(d);
          }
        }

        //log.fine(
        //    'Constructor => ${field.name} ${field.type.nullabilitySuffix}');
        if (!isListOrMapType(field.type)) {
          b.toThis = true;
        } else if (isListType(field.type)) {
          if (!b.toThis) {
            b.type = convertTypeReference(field.type);
          }

          // Get the default if presence
          var existingDefault = ctx.defaults[field.name];
          if (existingDefault != null) {
            var defaultValue = dartObjectToString(existingDefault);
            b.defaultTo = Code('$defaultValue');
          } else {
            b.defaultTo = Code('const []');
          }
        } else if (!b.toThis) {
          b.type = convertTypeReference(field.type);
        } else {
          log.fine('Contructor: ${field.name} pass through');
        }

        if ((ctx.requiredFields.containsKey(field.name) ||
                field.type.nullabilitySuffix != NullabilitySuffix.question) &&
            b.defaultTo == null) {
          //b.annotations.add(CodeExpression(Code('required')));
          b.required = true;
        }
      }));
    }

    if (ctx.constructorParameters.isNotEmpty) {
      if (!shouldBeConstant(ctx) ||
          ctx.clazz.unnamedConstructor?.isConst == true) {
        constructor.initializers.add(Code(
            'super(${ctx.constructorParameters.map((p) => p.name).join(',')})'));
      }
    }
  }));
}