Skip to content

Commit 21bb6b7

Browse files
nateboschmatanlurey
authored andcommitted
Generate with LibraryReader over LibraryElement (#239)
Similar to ConstantReader this will make it easier to use new utility methods as we add them. - Make `_element` public so that clients can still access the `LibraryElement` when needed. - Change the `generate` method signature and all implementations. - Wrap the argument in `builder.dart`.
1 parent aab7e08 commit 21bb6b7

File tree

8 files changed

+26
-26
lines changed

8 files changed

+26
-26
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
## 0.7.0
22

33
* **Breaking changes**
4-
* `Generator.generate` now operates on a `LibraryElement` rather than being
4+
* `Generator.generate` now operates on a `LibraryReader` rather than being
55
called for every `Element` within a library. Generators can iterate over
6-
elements using the `allElements` utility. `GeneratorForAnnotation` will
6+
elements using `LibraryReader.allElements`. `GeneratorForAnnotation` will
77
continue to call `generateForAnnotatedElement` repeatedly for each element.
88
* `GeneratorForAnnotation` passes in a `ConstantReader` for the annotation
99
instance rather than re-creating it using mirrors.
@@ -15,6 +15,7 @@
1515
* Removed `OutputFormatter` typedef.
1616
* Add `LibraryReader.allElements` - a utility to iterate across all `Element`
1717
instances contained in Dart library.
18+
* Add `LibraryReader.element` to get back to the `LibraryElement` instance.
1819

1920
## 0.6.1+1
2021

lib/src/builder.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:dart_style/dart_style.dart';
1010

1111
import 'generated_output.dart';
1212
import 'generator.dart';
13+
import 'library.dart';
1314
import 'utils.dart';
1415

1516
typedef String _OutputFormatter(String code);
@@ -195,10 +196,11 @@ class LibraryBuilder extends _Builder {
195196

196197
Stream<GeneratedOutput> _generate(LibraryElement library,
197198
List<Generator> generators, BuildStep buildStep) async* {
199+
var libraryReader = new LibraryReader(library);
198200
for (var gen in generators) {
199201
try {
200202
log.finer('Running $gen for $library');
201-
var createdUnit = await gen.generate(library, buildStep);
203+
var createdUnit = await gen.generate(libraryReader, buildStep);
202204

203205
if (createdUnit != null && createdUnit.isNotEmpty) {
204206
log.finest(() => 'Generated $createdUnit for $library');

lib/src/generator.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
import 'dart:async';
66

7-
import 'package:analyzer/dart/element/element.dart';
87
import 'package:build/build.dart';
98

9+
import 'library.dart';
10+
1011
/// A tool to generate Dart code based on a Dart library source.
1112
///
1213
/// During a build [generate] is called once per input library.
@@ -19,7 +20,7 @@ abstract class Generator {
1920
/// output is Dart code returned through the Future. If there is nothing to
2021
/// generate for this library may return null, or a Future that resolves to
2122
/// null or the empty string.
22-
Future<String> generate(LibraryElement element, BuildStep buildStep) => null;
23+
Future<String> generate(LibraryReader library, BuildStep buildStep) => null;
2324

2425
@override
2526
String toString() => this.runtimeType.toString();

lib/src/generator_for_annotation.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ abstract class GeneratorForAnnotation<T> extends Generator {
3535
TypeChecker get typeChecker => new TypeChecker.fromRuntime(T);
3636

3737
@override
38-
Future<String> generate(LibraryElement library, BuildStep buildStep) async {
39-
var elements = new LibraryReader(library)
40-
.allElements
38+
Future<String> generate(LibraryReader library, BuildStep buildStep) async {
39+
var elements = library.allElements
4140
.map((e) => new _AnnotatedElement(e, typeChecker.firstAnnotationOf(e)))
4241
.where((e) => e.annotation != null);
4342
var allOutput = await Future.wait(elements.map((e) =>

lib/src/library.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,27 @@ import 'package:analyzer/src/dart/resolver/scope.dart';
1010

1111
/// A high-level wrapper API with common functionality for [LibraryElement].
1212
class LibraryReader {
13-
final LibraryElement _element;
13+
final LibraryElement element;
1414

1515
Namespace _namespaceCache;
1616

17-
LibraryReader(this._element);
17+
LibraryReader(this.element);
1818

1919
Namespace get _namespace => _namespaceCache ??=
20-
new NamespaceBuilder().createExportNamespaceForLibrary(_element);
20+
new NamespaceBuilder().createExportNamespaceForLibrary(element);
2121

2222
/// Returns a top-level [ClassElement] publicly visible in by [name].
2323
///
2424
/// Unlike [LibraryElement.getType], this also correctly traverses identifiers
2525
/// that are accessible via one or more `export` directives.
2626
ClassElement findType(String name) =>
27-
_element.getType(name) ?? _namespace.get(name) as ClassElement;
27+
element.getType(name) ?? _namespace.get(name) as ClassElement;
2828

29-
/// Returns all of the declarations in this library, including the
30-
/// [LibraryElement] as the first item.
29+
/// All of the declarations in this library, including the [LibraryElement] as
30+
/// the first item.
3131
Iterable<Element> get allElements sync* {
32-
yield _element;
33-
for (var cu in _element.units) {
32+
yield element;
33+
for (var cu in element.units) {
3434
for (var compUnitMember in cu.unit.declarations) {
3535
yield* _getElements(compUnitMember);
3636
}

test/builder_test.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
@TestOn('vm')
66
import 'dart:async';
77

8-
import 'package:analyzer/dart/element/element.dart';
98
import 'package:build_test/build_test.dart';
109
import 'package:source_gen/source_gen.dart';
1110
import 'package:test/test.dart';
@@ -175,12 +174,12 @@ Map<String, String> _createPackageStub(String pkgName,
175174
/// Doesn't generate output for any element
176175
class _NoOpGenerator extends Generator {
177176
const _NoOpGenerator();
178-
Future<String> generate(LibraryElement element, _) => null;
177+
Future<String> generate(LibraryReader library, _) => null;
179178
}
180179

181180
class _BadOutputGenerator extends Generator {
182181
const _BadOutputGenerator();
183-
Future<String> generate(LibraryElement element, _) async => 'not valid code!';
182+
Future<String> generate(LibraryReader library, _) async => 'not valid code!';
184183
}
185184

186185
const pkgName = 'pkg';

test/src/comment_generator.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,14 @@ class CommentGenerator extends Generator {
1414
const CommentGenerator({this.forClasses: true, this.forLibrary: false});
1515

1616
@override
17-
Future<String> generate(LibraryElement library, _) async {
17+
Future<String> generate(LibraryReader library, _) async {
1818
var output = new StringBuffer();
1919
if (forLibrary) {
20-
output.writeln('// Code for "$library"');
20+
output.writeln('// Code for "${library.element}"');
2121
}
2222
if (forClasses) {
23-
for (var classElement in new LibraryReader(library)
24-
.allElements
25-
.where((e) => e is ClassElement)) {
23+
for (var classElement
24+
in library.allElements.where((e) => e is ClassElement)) {
2625
if (classElement.displayName.contains('GoodError')) {
2726
throw new InvalidGenerationSourceError(
2827
"Don't use classes with the word 'Error' in the name",

test/src/unformatted_code_generator.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44

55
import 'dart:async';
66

7-
import 'package:analyzer/dart/element/element.dart';
87
import 'package:source_gen/source_gen.dart';
98

109
/// Generates a single-line of unformatted code.
1110
class UnformattedCodeGenerator extends Generator {
1211
const UnformattedCodeGenerator();
1312

1413
@override
15-
Future<String> generate(LibraryElement element, _) async => unformattedCode;
14+
Future<String> generate(LibraryReader library, _) async => unformattedCode;
1615

1716
static const formattedCode = '''
1817
void hello() => print('hello');

0 commit comments

Comments
 (0)