-
Notifications
You must be signed in to change notification settings - Fork 107
Migrating to 0.7.x
source_gen
0.7.0 introduced some breaking changes to how Generator
s are run, use this guide to upgrade your usage.
The method signature has changed, but behavior is otherwise not impacted. Your GeneratorForAnnotation
will behave as before – generateForAnnotation
will continue to be called once per annotated element in the source library.
- Change the
annotation
argument togenerateForAnnotation
from an instance of the annotation to an instance ofConstantReader
. Pull fields from the reader using theread
method.
For example:
// Before
class SomeGenerator extends GeneratorForAnnotation<SomeAnnotation> {
@override
Future<String> generateForAnnotation(
Element element, SomeAnnotation annotation, BuildStep buildStep) {
//...
var someField = annotation.someField;
//...
}
}
// After
class SomeGenerator extends GeneratorForAnnotation<SomeAnnotation> {
@override
Future<String> generateForAnnotation(
Element element, SomeAnnotation annotation, BuildStep buildStep) {
//...
var someField = annotation.read('someField').stringValue;
//...
}
}
-
generateForAnnotatedElement
may get called for anElement
before the previous call'sFuture
has completed. In 0.6.0 the steps for each element were serialized, while in 0.7.0 they may run in parallel. This will only impact Generators which have some global state and a dependency on the order of the build which should be avoided.
These will most likely only impact tests:
- The output will look a little different - blocks will no longer be commented with the element causing a snippet of code to get generated
- Exceptions thrown will cause no code to get generated at all rather than insert comments in the generated output with the error message
- The
generate
method, if called manually in a test, should only be called for an entire library at a time.
The generate
method is now called once per library rather than once per element within a library. Iterating over elements, if required, is now the responsibility of the generator.
- Change the signature to take a
LibraryReader
as the first argument. - If required to visit every element within a library, iterate over them with
LibraryReader.allElements
.
For example
// Before
class SomeGenerator extends Generator {
@override
Future<String> generate(Element element, BuildStep buildStep) {
if (element is LibraryElement) {
// Do library stuff
return result;
} else {
// Do non-library stuff
return result;
}
}
}
// After
class SomeGenerator extends Generator {
@override
Future<String> generate(LibraryReader library, BuildStep buildStep) {
var generated = new StringBuffer();
var libraryElement = library.element
// Do library stuff
generated.writeln(result);
for(var element in library.allElements) {
// Do non-library stuff
generated.writeln(result);
}
return '$generated';
}
}
- The output will look a little different - blocks will no longer be commented with which element causes a snippet of code to get generated unless you add the comment manually
- Exceptions thrown will cause no code to get generated at all rather than insert comments in the generated output with the error message - if these comments are needed (usually for backwards compatibility in tests) catch exceptions manually to write these comments and be sure to
log.severe
so that the build can be marked as a failure overall - The
generate
method, if called manually in a test, should only be called for an entire library at a time.
Depending on whether the isStandalone
argument was passed as true
, construct either a PartBuilder
(no isStandalone
argument, or passing false
) or a LibraryBuilder
('isStandalone: true`).