如何读取注释字段及其值(代码生成)

时间:2019-08-29 05:23:23

标签: flutter dart

我一直在努力从注释中获取字段。

我正在使用源代码生成器从注释中生成窗口小部件,但似乎无法使用注释字段,如何访问这些字段和值。

我的注释:

class CoreEntity {
  final String label;

  const CoreEntity({
    this.label,
  });
}

使用注释:

@CoreEntity(
  label: 'User',
)
class User {
  String email;
}

我的窗口小部件生成器:

class CoreWidgetGenerator extends GeneratorForAnnotation<CoreEntity> {
  @override
  FutureOr<String> generateForAnnotatedElement(
      Element element, ConstantReader annotation, BuildStep buildStep) {
    return _generateWidgetSource(element);
  }

  String _generateWidgetSource(Element element) {
    final anotData = element.metadata;
    for (ElementAnnotation el in anotData) {
      el.computeConstantValue();
      var elVisitor = ModelVisitor();
      el.element.visitChildren(elVisitor);
      print("1 ${elVisitor.className}"); // this prints out null
      print("2 ${elVisitor.fields}"); // this prints out empty list {}
    }
}

class ModelVisitor extends SimpleElementVisitor {
  DartType className;
  Map<String, DartType> fields = Map();

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

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

    return super.visitFieldElement(element);
  }
}

pubspec.yaml中的软件包

dependencies:
  build: ^1.1.6
  source_gen: ^0.9.4+4 
  core_widget:
    path: ../core_widgets

构建脚本(build.yaml)

targets:
  $default:
    builders:
      core_gen|core_widget:
        enabled: true

builders:
  core_widget:
      target: ":core_gen"
      import: "package:core_gen/builder.dart"
      builder_factories: ["coreWidget"]
      build_extensions: {".dart":[".core_widget.g.part"]}
      auto_apply: dependents
      build_to: cache
      applies_builders: ["source_gen|combining_builder"]

参考资料|我已经做过研究,但是没有运气。

1 个答案:

答案 0 :(得分:1)

您已经可以通过ConstantReader

访问注释属性
class CoreWidgetGenerator extends GeneratorForAnnotation<CoreEntity> {
  @override
  FutureOr<String> generateForAnnotatedElement(
      Element element, ConstantReader annotation, BuildStep buildStep) {
    return _generateWidgetSource(element, annotation);
  }

  String _generateWidgetSource(Element element, ConstantReader annotation) {
    print(annotation.read('label').stringValue);  
  }
}

但是,如果要检索ClassElement字段的注释信息,可以使用TypeChecker

注释

class CoreProperty {
  final String label;

  const CoreProperty({ this.label});
}

用法

@CoreEntity(label: 'User')
class User {

  @CoreProperty(label: 'Email')
  String email;
}
final _coreChecker = const TypeChecker.fromRuntime(CoreProperty);

class CoreWidgetGenerator extends GeneratorForAnnotation<CoreEntity> {
  @override
  FutureOr<String> generateForAnnotatedElement(
      Element element, ConstantReader annotation, BuildStep buildStep) {
    return _generateWidgetSource(element as ClassElement, annotation);
  }

  String _generateWidgetSource(ClassElement element, ConstantReader annotation) {

    for (var f in element.fields) {
      if (_coreChecker.hasAnnotationOfExact(f)) {
        print(_coreChecker
          .firstAnnotationOfExact(f)
          .getField('label')
          .toStringValue()
        );
      }
    }
  }
}