From 39f1254750d2c8977e07d1ae7b30cf7f596fd888 Mon Sep 17 00:00:00 2001 From: Tobe O Date: Tue, 21 Aug 2018 11:16:41 -0400 Subject: [PATCH] Add ReflectorLibraryGenerator --- .../lib/angel_container_generator.dart | 7 +++ .../lib/src/generator.dart | 28 ++++++++++++ .../lib/src/library_generator.dart | 43 +++++++++++++++++++ angel_container_generator/lib/src/util.dart | 12 +++--- angel_container_generator/pubspec.yaml | 2 + 5 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 angel_container_generator/lib/angel_container_generator.dart create mode 100644 angel_container_generator/lib/src/generator.dart create mode 100644 angel_container_generator/lib/src/library_generator.dart diff --git a/angel_container_generator/lib/angel_container_generator.dart b/angel_container_generator/lib/angel_container_generator.dart new file mode 100644 index 00000000..5bb390f9 --- /dev/null +++ b/angel_container_generator/lib/angel_container_generator.dart @@ -0,0 +1,7 @@ +import 'package:build/build.dart'; +import 'package:source_gen/source_gen.dart'; +import 'src/generator.dart'; + +Builder angelContainerBuilder(BuilderOptions builderOptions) { + return new PartBuilder([new AngelContainerGenerator()], '.reflector.g.dart'); +} diff --git a/angel_container_generator/lib/src/generator.dart b/angel_container_generator/lib/src/generator.dart new file mode 100644 index 00000000..7c1419bd --- /dev/null +++ b/angel_container_generator/lib/src/generator.dart @@ -0,0 +1,28 @@ +import 'dart:async'; + +import 'package:analyzer/dart/element/element.dart'; +import 'package:angel_container/angel_container.dart'; +import 'package:build/build.dart'; +import 'package:source_gen/source_gen.dart'; + +import 'library_generator.dart'; +import 'util.dart'; + +class AngelContainerGenerator + extends GeneratorForAnnotation { + @override + Future generateForAnnotatedElement( + Element element, ConstantReader annotation, BuildStep buildStep) async { + if (element is LibraryElement) { + var reader = new GenerateReflectorReader(annotation); + var generator = new ReflectorLibraryGenerator(element, reader) + ..generate(); + return generator.toSource(); + } else if (element is ClassElement) { + return null; + } else { + throw new UnsupportedError( + '@GenerateReflector() can only be added to a library or class element.'); + } + } +} diff --git a/angel_container_generator/lib/src/library_generator.dart b/angel_container_generator/lib/src/library_generator.dart new file mode 100644 index 00000000..4f2998df --- /dev/null +++ b/angel_container_generator/lib/src/library_generator.dart @@ -0,0 +1,43 @@ +import 'package:analyzer/dart/element/element.dart'; +import 'package:code_builder/code_builder.dart'; +import 'package:recase/recase.dart'; + +import 'util.dart'; + +class ReflectorLibraryGenerator { + final LibraryElement element; + final GenerateReflectorReader annotation; + Library _lib; + + ReflectorLibraryGenerator(this.element, this.annotation); + + String toSource() { + return _lib.accept(new DartEmitter()).toString(); + } + + void generate() { + _lib = new Library((lib) { + lib.body.add(generateReflectorClass()); + }); + } + + Class generateReflectorClass() { + return new Class((clazz) { + // Select the name + if (annotation.name?.isNotEmpty == true) { + clazz.name = annotation.name; + } else { + var rc = new ReCase(element.name); + clazz.name = rc.pascalCase + 'Reflector'; + } + + // implements Reflector + clazz.implements.add(refer('Reflector')); + + // Add a const constructor + clazz.constructors.add(new Constructor((b) { + b..constant = true; + })); + }); + } +} diff --git a/angel_container_generator/lib/src/util.dart b/angel_container_generator/lib/src/util.dart index d5159150..716c066e 100644 --- a/angel_container_generator/lib/src/util.dart +++ b/angel_container_generator/lib/src/util.dart @@ -8,14 +8,14 @@ const TypeChecker generateReflectorTypeChecker = /// Reads data from a [GenerateReflector] annotation. class GenerateReflectorReader { - final ConstantReader constantReader; + final ConstantReader annotation; - GenerateReflectorReader(this.constantReader); + GenerateReflectorReader(this.annotation); - String get name => constantReader.peek('name')?.stringValue; + String get name => annotation.peek('name')?.stringValue; List get types => - constantReader + annotation .peek('types') ?.listValue ?.map((o) => ConstantReader(o).typeValue) @@ -23,7 +23,7 @@ class GenerateReflectorReader { []; List get symbols => - constantReader + annotation .peek('symbols') ?.listValue ?.map((o) => ConstantReader(o).symbolValue) @@ -31,5 +31,5 @@ class GenerateReflectorReader { []; List get functions => - constantReader.peek('functions')?.listValue ?? []; + annotation.peek('functions')?.listValue ?? []; } diff --git a/angel_container_generator/pubspec.yaml b/angel_container_generator/pubspec.yaml index 997904b2..6d640582 100644 --- a/angel_container_generator/pubspec.yaml +++ b/angel_container_generator/pubspec.yaml @@ -9,6 +9,8 @@ dependencies: angel_container: ^1.0.0-alpha build: ^0.12.0 build_config: ^0.3.0 + code_builder: ^3.0.0 + recase: ^2.0.0 source_gen: ^0.9.0 dev_dependencies: build_runner: ^0.10.0 \ No newline at end of file