<commit_before>part of 'parser.dart';

/// Parses a [MoorView] from a Dart class.
class ViewParser {
  final MoorDartParser base;

  ViewParser(this.base);

  Future<MoorView?> parseView(
      ClassElement element, List<MoorTable> tables) async {
    final name = await _parseViewName(element);
    final columns = (await _parseColumns(element)).toList();
    final staticReferences =
        (await _parseStaticReferences(element, tables)).toList();
    final dataClassInfo = _readDataClassInformation(columns, element);
    final query = await _parseQuery(element, staticReferences, columns);

    final view = MoorView(
      declaration: DartViewDeclaration(element, base.step.file),
      name: name,
      dartTypeName: dataClassInfo.enforcedName,
      existingRowClass: dataClassInfo.existingClass,
      entityInfoName: '\$${element.name}View',
      staticReferences: staticReferences.map((ref) => ref.declaration).toList(),
      viewQuery: query,
    );

    view.columns = columns;
    return view;
  }

  _DataClassInformation _readDataClassInformation(
      List<MoorColumn> columns, ClassElement element) {
    DartObject? useRowClass;
    String? dataClassName;

    for (final annotation in element.metadata) {
      final computed = annotation.computeConstantValue();
      final annotationClass = computed!.type!.element!.name;

      if (annotationClass == 'DriftView') {
        dataClassName = computed.getField('dataClassName')?.toStringValue();
      } else if (annotationClass == 'UseRowClass') {
        useRowClass = computed;
      }
    }

    if (dataClassName != null && useRowClass != null) {
      base.step.reportError(ErrorInDartCode(
        message: "A table can't be annotated with both @DataClassName and "
            '@UseRowClass',
        affectedElement: element,
      ));
    }

    FoundDartClass? existingClass;
    String? constructorInExistingClass;
    bool? generateInsertable;

    var name = dataClassName ?? dataClassNameForClassName(element.name);

    if (useRowClass != null) {
      final type = useRowClass.getField('type')!.toTypeValue();
      constructorInExistingClass =
          useRowClass.getField('constructor')!.toStringValue()!;
      generateInsertable =
          useRowClass.getField('generateInsertable')!.toBoolValue()!;

      if (type is InterfaceType) {
        existingClass = FoundDartClass(type.element, type.typeArguments);
        name = type.element.name;
      } else {
        base.step.reportError(ErrorInDartCode(
          message: 'The @UseRowClass annotation must be used with a class',
          affectedElement: element,
        ));
      }
    }

    final verified = existingClass == null
        ? null
        : validateExistingClass(columns, existingClass,
            constructorInExistingClass!, generateInsertable!, base.step);
    return _DataClassInformation(name, verified);
  }

  Future<String> _parseViewName(ClassElement element) async {
    for (final annotation in element.metadata) {
      final computed = annotation.computeConstantValue();
      final annotationClass = computed!.type!.element!.name;

      if (annotationClass == 'DriftView') {
        final name = computed.getField('name')?.toStringValue();
        if (name != null) {
          return name;
        }
        break;
      }
    }

    return element.name.snakeCase;
  }

  Future<Iterable<MoorColumn>> _parseColumns(ClassElement element) async {
    final columnNames = element.allSupertypes
        .map((t) => t.element)
        .followedBy([element])
        .expand((e) => e.fields)
        .where((field) =>
            isExpression(field.type) &&
            field.getter != null &&
            !field.getter!.isSynthetic)
        .map((field) => field.name)
        .toSet();

    final fields = columnNames.map((name) {
      final getter = element.getGetter(name) ??
          element.lookUpInheritedConcreteGetter(name, element.library);
      return getter!.variable;
    }).toList();

    final results = await Future.wait(fields.map((field) async {
      final dartType = (field.type as InterfaceType).typeArguments[0];
      final typeName = dartType.element!.name!;<commit_msg>Fix ViewParser not support alias column<commit_after>part of 'parser.dart';

/// Parses a [MoorView] from a Dart class.
class ViewParser {
  final MoorDartParser base;

  ViewParser(this.base);

  Future<MoorView?> parseView(
      ClassElement element, List<MoorTable> tables) async {
    final name = await _parseViewName(element);
    final columns = (await _parseColumns(element)).toList();
    final staticReferences =
        (await _parseStaticReferences(element, tables)).toList();
    final dataClassInfo = _readDataClassInformation(columns, element);
    final query = await _parseQuery(element, staticReferences, columns);

    final view = MoorView(
      declaration: DartViewDeclaration(element, base.step.file),
      name: name,
      dartTypeName: dataClassInfo.enforcedName,
      existingRowClass: dataClassInfo.existingClass,
      entityInfoName: '\$${element.name}View',
      staticReferences: staticReferences.map((ref) => ref.declaration).toList(),
      viewQuery: query,
    );

    view.columns = columns;
    return view;
  }

  _DataClassInformation _readDataClassInformation(
      List<MoorColumn> columns, ClassElement element) {
    DartObject? useRowClass;
    String? dataClassName;

    for (final annotation in element.metadata) {
      final computed = annotation.computeConstantValue();
      final annotationClass = computed!.type!.element!.name;

      if (annotationClass == 'DriftView') {
        dataClassName = computed.getField('dataClassName')?.toStringValue();
      } else if (annotationClass == 'UseRowClass') {
        useRowClass = computed;
      }
    }

    if (dataClassName != null && useRowClass != null) {
      base.step.reportError(ErrorInDartCode(
        message: "A table can't be annotated with both @DataClassName and "
            '@UseRowClass',
        affectedElement: element,
      ));
    }

    FoundDartClass? existingClass;
    String? constructorInExistingClass;
    bool? generateInsertable;

    var name = dataClassName ?? dataClassNameForClassName(element.name);

    if (useRowClass != null) {
      final type = useRowClass.getField('type')!.toTypeValue();
      constructorInExistingClass =
          useRowClass.getField('constructor')!.toStringValue()!;
      generateInsertable =
          useRowClass.getField('generateInsertable')!.toBoolValue()!;

      if (type is InterfaceType) {
        existingClass = FoundDartClass(type.element, type.typeArguments);
        name = type.element.name;
      } else {
        base.step.reportError(ErrorInDartCode(
          message: 'The @UseRowClass annotation must be used with a class',
          affectedElement: element,
        ));
      }
    }

    final verified = existingClass == null
        ? null
        : validateExistingClass(columns, existingClass,
            constructorInExistingClass!, generateInsertable!, base.step);
    return _DataClassInformation(name, verified);
  }

  Future<String> _parseViewName(ClassElement element) async {
    for (final annotation in element.metadata) {
      final computed = annotation.computeConstantValue();
      final annotationClass = computed!.type!.element!.name;

      if (annotationClass == 'DriftView') {
        final name = computed.getField('name')?.toStringValue();
        if (name != null) {
          return name;
        }
        break;
      }
    }

    return element.name.snakeCase;
  }

  Future<Iterable<MoorColumn>> _parseColumns(ClassElement element) async {
    final columnNames = element.allSupertypes
        .map((t) => t.element)
        .followedBy([element])
        .expand((e) => e.fields)
        .where((field) =>
            (isExpression(field.type) || isColumn(field.type)) &&
            field.getter != null &&
            !field.getter!.isSynthetic)
        .map((field) => field.name)
        .toSet();

    final fields = columnNames.map((name) {
      final getter = element.getGetter(name) ??
          element.lookUpInheritedConcreteGetter(name, element.library);
      return getter!.variable;
    }).toList();

    final results = await Future.wait(fields.map((field) async {
      final dartType = (field.type as InterfaceType).typeArguments[0];
      final typeName = dartType.element!.name!;
{'fraction_non_alphanumeric': 0.1118640038040894, 'fraction_numerical': 0.00023775558725630053, 'mean_word_length': 3.0544578313253012, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '927544', 'n_tokens_mistral': 2390, 'n_tokens_neox': 2286, 'n_words': 503}