Skip to content

Change Generator to run on LibraryElement #231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
## 0.7.0

* **Breaking changes**
* `Generator.generate` now operates on a `LibraryElement` rather than being
called for every `Element` within a library. Generators can iterate over
elements using the `allElements` utility. `GeneratorForAnnotation` will
continue to call `generateForAnnotatedElement` repeatedly for each element.
* `GeneratorForAnnotation` passes in a `ConstantReader` for the annotation
instance rather than re-creating it using mirrors.
* Removed `JsonSerializable` and related classes. These are moved to
`package:json_serializable`.
* Removed `lib/builder.dart`. Import through `source_gen.dart` instead.
Expand Down
177 changes: 0 additions & 177 deletions lib/src/annotation.dart

This file was deleted.

33 changes: 8 additions & 25 deletions lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,6 @@ class GeneratorBuilder extends Builder {
contentBuffer.writeln('');
contentBuffer.writeln(_headerLine);
contentBuffer.writeln('// Generator: ${output.generator}');
contentBuffer
.writeln('// Target: ${friendlyNameForElement(output.sourceMember)}');
contentBuffer.writeln(_headerLine);
contentBuffer.writeln('');

Expand Down Expand Up @@ -160,35 +158,20 @@ class GeneratorBuilder extends Builder {
String toString() => 'GeneratorBuilder:$generators';
}

Stream<GeneratedOutput> _generate(LibraryElement unit,
Stream<GeneratedOutput> _generate(LibraryElement library,
List<Generator> generators, BuildStep buildStep) async* {
List<Element> elements;
try {
elements = allElements(unit).toList();
} catch (e) {
log.fine('Resolve error details:\n$e');
log.severe('Failed to resolve ${buildStep.inputId}.');
return;
}
for (var element in elements) {
yield* _processUnitMember(element, generators, buildStep);
}
}

Stream<GeneratedOutput> _processUnitMember(
Element element, List<Generator> generators, BuildStep buildStep) async* {
for (var gen in generators) {
try {
log.finer('Running $gen for $element');
var createdUnit = await gen.generate(element, buildStep);
log.finer('Running $gen for $library');
var createdUnit = await gen.generate(library, buildStep);

if (createdUnit != null) {
log.finest(() => 'Generated $createdUnit for $element');
yield new GeneratedOutput(element, gen, createdUnit);
if (createdUnit != null && createdUnit.isNotEmpty) {
log.finest(() => 'Generated $createdUnit for $library');
yield new GeneratedOutput(gen, createdUnit);
}
} catch (e, stack) {
log.severe('Error running $gen for $element.', e, stack);
yield new GeneratedOutput.fromError(element, gen, e, stack);
log.severe('Error running $gen for $library.', e, stack);
yield new GeneratedOutput.fromError(gen, e, stack);
}
}
}
Expand Down
10 changes: 2 additions & 8 deletions lib/src/generated_output.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,23 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library source_gen.generated_output;

import 'dart:convert';

import 'package:analyzer/dart/element/element.dart';

import 'generator.dart';

class GeneratedOutput {
final Element sourceMember;
final String output;
final Generator generator;
final error;
final StackTrace stackTrace;

bool get isError => error != null;

GeneratedOutput(this.sourceMember, this.generator, this.output)
GeneratedOutput(this.generator, this.output)
: error = null,
stackTrace = null;

GeneratedOutput.fromError(this.sourceMember, this.generator, Object error,
[this.stackTrace])
GeneratedOutput.fromError(this.generator, Object error, [this.stackTrace])
: this.output = _outputFromError(error),
this.error = error;
}
Expand Down
22 changes: 8 additions & 14 deletions lib/src/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,24 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library source_gen.generator;

import 'dart:async';

import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';

/// A simple API surface for emitting Dart source code from existing code.
/// A tool to generate Dart code based on a Dart library source.
///
/// Clients should _extend_ this class and _override_ [generate]:
/// ```dart
/// class MyGenerator extends Generator {
/// Future<String> generate(Element element, BuildStep buildStep) async {
/// // Return a string representing the code to emit.
/// }
/// }
/// ```
/// During a build [generate] is called once per input library.
abstract class Generator {
const Generator();

/// Override to return source code for a given [element].
/// Generates Dart code for an input Dart library.
///
/// May return `null` to signify "nothing to generate".
Future<String> generate(Element element, BuildStep buildStep) => null;
/// May create additional outputs through the `buildStep`, but the 'primary'
/// output is Dart code returned through the Future. If there is nothing to
/// generate for this library may return null, or a Future that resolves to
/// null or the empty string.
Future<String> generate(LibraryElement element, BuildStep buildStep) => null;

@override
String toString() => this.runtimeType.toString();
Expand Down
Loading