generateValidator static method

String generateValidator(
  1. Element element,
  2. bool createBaseClass
)

Implementation

static String generateValidator(Element element, bool createBaseClass) {
  var classElement = element.asClassElement();
  if (classElement.kind.name == 'ENUM') return '';
  var superTypeElement = classElement.supertype!.element;

  var annotation = TypeChecker.fromRuntime(Validatable)
      .firstAnnotationOf(superTypeElement);

  var superClassIsValidatable = annotation != null;

  var className = classElement.name;

  var fieldDescriptors = _getFieldDescriptors(classElement);

  var errorCallBuffer = StringBuffer();
  var validationMethodBuffer = StringBuffer();

  for (var fieldDescriptor in fieldDescriptors) {
    var errorLine = '''
        if ((error = validate${fieldDescriptor.pascalName}(entity.${fieldDescriptor.name})) != null) {
          errors.add(error!);
        }
    ''';
    errorCallBuffer.writeln(errorLine);

    var validationMethodCode = _createValidationMethod(fieldDescriptor);
    validationMethodBuffer.writeln(validationMethodCode);
  }

  var validatorClassName =
      createBaseClass ? '${className}ValidatorBase' : '${className}Validator';

  var callToSuperCreate = superClassIsValidatable ? ' : super.create()' : '';
  var construction =
      '''${className}Validator${createBaseClass ? 'Base' : ''}.create()$callToSuperCreate;''';

  var singletonAndFactory = createBaseClass
      ? ''
      : '''
    static final ${className}Validator _singleton = ${className}Validator.create();
    factory ${className}Validator() => _singleton;
    ''';

  var extendsClause = !superClassIsValidatable
      ? ''
      : 'extends ${superTypeElement.name}Validator';

  var returnStatement = !superClassIsValidatable
      ? 'return ErrorList(errors);'
      : 'return ErrorList.merge(super.validate(entity), errors);';

  var ret = '''

  class $validatorClassName $extendsClause  implements Validator {

      $construction

      $singletonAndFactory

      $validationMethodBuffer

      @override
      ErrorList validate(covariant $className entity) {
        var errors = <ValidationError>[];

        ${errorCallBuffer.isNotEmpty ? 'ValidationError? error;' : ''}
        $errorCallBuffer

        $returnStatement
      }

      @override
      void validateThrowing(covariant $className entity) {
        var errors = validate(entity);
        if (errors.validationErrors.isNotEmpty) throw errors;
      }
    }

  ''';
  return ret;
}