generateForAnnotatedElement method
Future<String>
generateForAnnotatedElement(
- Element element,
- ConstantReader annotation,
- BuildStep buildStep
Implement to return source code to generate for element
.
This method is invoked based on finding elements annotated with an
instance of T
. The annotation
is provided as a ConstantReader
.
Supported return values include a single String or multiple String instances within an Iterable or Stream. It is also valid to return a Future of String, Iterable, or Stream.
Implementations should return null
when no content is generated. Empty
or whitespace-only String instances are also ignored.
Implementation
@override
Future<String> generateForAnnotatedElement(
Element element,
ConstantReader annotation,
BuildStep buildStep,
) async {
if (element.isPrivate) {
throw InvalidGenerationSourceError(
'Widgetbook annotations cannot be applied to private elements',
element: element,
);
}
final locales = <String>[];
final node = await buildStep.resolver.astNodeFor(element);
if (node != null) {
final entities = node.childEntities.toList();
if (entities[0] is SimpleIdentifier &&
entities[1] is Token &&
entities[2] is ListLiteral) {
final listLiteral = entities[2] as ListLiteral;
// TODO this is likely the most flaky code that has ever been written
// check the following cases
// - Locale('en')
// - const Locale('en')
// - Locale('en', 'US')
// - const Locale('en', 'US')
// - additional methods, e.g. Locale.fromString('...') and similar stuff
// Maybe it's best to just use a regex
final localeDefinitions = listLiteral.elements.toList();
for (final localeDefinition in localeDefinitions) {
// If expression starts WITHOUT const e.g. Local('en'), this will
// be called
if (localeDefinition is MethodInvocation) {
final stringLiteral =
localeDefinition.argumentList.arguments.first as StringLiteral;
final value = stringLiteral.stringValue!;
locales.add(value);
}
// If expression starts WITH const e.g. const Local('en'), this will
// be called
if (localeDefinition is InstanceCreationExpression) {
final stringLiteral =
localeDefinition.argumentList.arguments.first as StringLiteral;
final value = stringLiteral.stringValue!;
locales.add(value);
}
}
}
}
final data = WidgetbookLocalesData(
name: element.name!,
importStatement: element.importStatement,
dependencies: [],
locales: locales,
);
return [data].toJson();
}