Чтение аннотаций на методах получения классов для генерации исходного кода. - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь создать генератор исходного кода, который создает класс на основе аннотированных полей. Эти поля будут получателями, однако я пока не могу получить аннотацию. Между тем, если я преобразую эти поля в финалы, поиск аннотаций сработает.

@MyClassAnnotation()
class MyClass{
  // Works as expected
  @MyFieldAnnotation()
  final foo = "foo";

  // Cannot retrieve this annotation
  @MyFieldAnnotation()
  String get bar => "bar";
}

ModelVisitor, который я использую для получения метаданных.

class ModelVisitor extends SimpleElementVisitor {
  DartType className;
  Map<String, DartType> fields = {};
  Map<String, dynamic> metaData = {};

  @override
  visitConstructorElement(ConstructorElement element) {
    className = element.type.returnType;
  }

  @override
  visitFieldElement(FieldElement element) {
    fields[element.name] = element.type;
    metaData[element.name] = element.metadata;
  }
}

Альтернативная реализация, которая обеспечивает те же результаты

class StateGenerator extends GeneratorForAnnotation<MyClassAnnotation> {
  @override
  generateForAnnotatedElement(
      Element element, ConstantReader annotation, BuildStep buildStep) async {
    final values = <String>{};

    if (element is ClassElement && !element.isEnum) {
      for (final field in element.fields) {
        final annotationObject = getFieldAnnotation<MyFieldAnnotation>(field);
        if (annotationObject != null) {
          /// ...
        }
      }
    }

    /// ...
  }

  DartObject getFieldAnnotation<T>(Element element) {
    final annotations = TypeChecker.fromRuntime(T).annotationsOf(element);
    if (annotations.isEmpty) {
      return null;
    }
    if (annotations.length > 1) {
      throw Exception(
          "You tried to add multiple @$StateField() annotations to the "
          "same element (${element.name}), but that's not possible.");
    }
    return annotations.single;
  }
}
...