generateForAnnotatedElement method
FutureOr<String>
generateForAnnotatedElement(
- Element element,
- ConstantReader annotation,
- 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
FutureOr<String> generateForAnnotatedElement(
Element element, ConstantReader annotation, BuildStep _) {
if (!(element is ClassElement)) {
throw Exception('Only annotate mixins with `@SumType()`.');
}
try {
final clazz = ClassModel(element, annotation);
if (clazz.fields.isEmpty) {
throw CodegenException('no alternatives defined for ${clazz.mixinName}');
}
const tyArg = r'__T$';
final otherwise = clazz.fieldNames.contains('otherwise') ? r'otherwise__$' : 'otherwise';
final toStringMethod = '''
@override
String toString() {
final __x\$ = iswitch(${clazz.toStringSwitch});
return '${clazz.mixinName}.\${__x\$}';
}
''';
final code = '''
/// This data class has been generated from ${clazz.mixinName}
abstract class ${clazz.factoryName} {
${clazz.factoryMethods}
}
abstract class ${clazz.baseClassName}${clazz.typeArgsWithParens} {
const ${clazz.baseClassName}();
${clazz.getterDecls}
$tyArg iswitch<$tyArg>({
${clazz.switchParams(tyArg, SwitchMode.Required)}
});
$tyArg iswitcho<$tyArg>({
${clazz.switchParams(tyArg, SwitchMode.Optional)},
${clazz.config.nnbd ? 'required' : '@required'} $tyArg Function() $otherwise,
});
}
@immutable
class ${clazz.className}${clazz.typeArgsWithParens}
extends ${clazz.baseClassName}${clazz.typeArgsWithParens}
with ${clazz.mixinName}${clazz.typeArgsWithParens}
{
${clazz.fieldDecls}
${clazz.getterImpls}
const ${clazz.className}({
${clazz.constructorParams}
}) : ${clazz.constructorInitializers};
@override
$tyArg iswitch<$tyArg>({
${clazz.switchParams(tyArg, SwitchMode.Required)},
}) {
${clazz.iswitchBody}
}
@override
$tyArg iswitcho<$tyArg>({
${clazz.switchParams(tyArg, SwitchMode.Optional)},
${clazz.config.nnbd ? 'required' : '@required'} $tyArg Function() $otherwise,
}) {
return iswitch(
${clazz.iswitchArgsFromOtherwise(otherwise)}
);
}
${clazz.config.genEqHashCode ? eqImpl(clazz.className, clazz.internalFieldNames) : ''}
${clazz.config.genEqHashCode ? hashCodeImpl(clazz.internalFieldNames) : ''}
${clazz.config.genToString ? toStringMethod : ''}
}
''';
//print(code);
return code;
} on CodegenException catch (e) {
e.generatorName = 'SumType';
rethrow;
}
}