generateForAnnotatedElement method
FutureOr<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
FutureOr<String> generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep) async {
GeneratorLog.info(title: 'Annotation Found', data: annotation.getName);
GeneratorLog.info(title: 'Code Generation for Annotation Started');
String code = '';
GeneratorLog.info(title: 'Main Code Generation Started...');
String className = element.name ?? 'UnnamedClass';
List<Variable> variablesList = List<Variable>.empty(growable: true);
ElementVisitor visitor = ElementVisitor();
element.visitChildren(visitor);
List<Element> fields = element.children.where((child) => child.kind == ElementKind.FIELD).toList();
List<Element> constructors = element.children.where((child) => child.kind == ElementKind.CONSTRUCTOR).toList();
GeneratorLog.info(title: 'Generating Variables and Checking DartTypes...');
for (var item in fields) {
DartType? selectedVisitorField = visitor.fieldElements[item.name];
// code += selectedVisitorField == null ? '' : Prints.dartTypeInfo(selectedVisitorField);
Variable variable = Variable(
name: item.name ?? Strings.unnamedVariable,
type: selectedVisitorField,
typeString: selectedVisitorField?.toString(),
isCoreType: selectedVisitorField?.isDartCoreList == true ? selectedVisitorField?.isCoreTypeFromList : selectedVisitorField?.isCoreType,
isFinal: item.declaration.toString().contains('final'),
hasRequired: constructors.first.children.isEmpty ? null : constructors.first.children.firstWhere((e) => e.name == item.name).declaration.toString().contains('required '),
isNullable: item.declaration?.toString().split(' ').first.contains('?'),
isEnum: selectedVisitorField?.isEnum,
isList: selectedVisitorField?.isDartCoreList,
);
variablesList.add(variable);
}
GeneratorLog.info(title: 'Commenting Started');
code += AddCode.addCommentLine(' This File is Generated by ${PackageAuthorInfo.packageNameDescription}');
code += AddCode.addCommentLine(' [$className] Annotated with [${PackageAuthorInfo.annotationName}] with [${annotation.getName}] mode');
code += AddCode.addCommentLine(' Including:');
code += AddCode.addCommentLine(' Model Class, Entity Class and Mapper Class,');
code += AddCode.addCommentLine(' Model Classes includes [toJson] and [fromJson] functions, and Entity Classes are not!');
code += AddCode.addCommentLine(' Mappers will convert every filed in the class including [SubClasses], they should be annotated as well.');
code += AddCode.addCommentLine(
' [${PackageAuthorInfo.annotationName}] Annotation will generate all these fields for all Classes, so all subclasses should decorated with annotation to generate model, entity and mapper to use them here');
code += AddCode.addCommentLine(' [Enums] also supported and they will be detected and count into account for mappers and also json conversion');
annotation.getFreezed == true ? code += AddCode.addCommentLine(' Classes are decorated with [Freezed], other functions will generate with [Freezed]') : null;
code += AddCode.addSpace();
code += AddCode.addCommentLine(' Details:');
code += AddCode.addCommentLine(' Class: ${annotation.getAs ?? className}');
code += AddCode.addCommentLine(' Constructors Count: ${constructors.length}');
code += AddCode.addCommentLine(' Variables Count: ${variablesList.length}');
code += AddCode.addSpace();
GeneratorLog.info(title: 'Generating Classes (Model and Entity) for', data: className);
code += AddCode.addCommentLine(' ==> Model Class:');
GeneratorData generatorData = GeneratorData(
className: annotation.getAs ?? className,
variablesList: variablesList,
isFreezed: annotation.getFreezed,
extended: annotation.getIsExtended,
);
code += AddClass().generate(generatorData.copyWith(annotationType: AnnotationTypes.model));
code += AddCode.addCommentLine(' ==> Entity Class:');
code += AddClass().generate(generatorData.copyWith(annotationType: AnnotationTypes.entity));
GeneratorLog.info(title: 'Generating Mapper Class for', data: className);
code += AddCode.addCommentLine(' ==> Mapper Classes:');
code += AddMapper().generate(generatorData);
GeneratorLog.info(title: 'Completing Code Generation and Preparing Files...');
return code;
}