generateValidator static method

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

Implementation

static String generateValidator(Element element, bool createBaseClass) {
  if (element is EnumElement) return '';
  var classElement = element.asInterfaceElement();
  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();
  final nullValidationMethodBuffer = StringBuffer();

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

    var validationMethodCode =
        _createValidationMethod(fieldDescriptor, className);
    validationMethodBuffer.writeln(validationMethodCode);

    final nullValidationMethodCode =
        _createNullValidationMethod(fieldDescriptor, className);
    if (nullValidationMethodCode.isNotEmpty) {
      nullValidationMethodBuffer.writeln(nullValidationMethodCode);
    }
  }

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

  var construction =
      '''const \$${className}Validator${createBaseClass ? 'Base' : ''}();''';

  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

      $validationMethodBuffer

      $nullValidationMethodBuffer

      @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;
}