generateForAnnotatedElement method

  1. @override
FutureOr<String> generateForAnnotatedElement(
  1. Element element,
  2. ConstantReader annotation,
  3. 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 `@DataClass()`.');
  }
  try {
    final clazz = ClassModel(element, annotation);
    final toStringMethod = '''
      @override
      String toString() {
        return '${clazz.mixinName}(${clazz.toStringFields})';
      }
    ''';
    final code = '''
      /// This data class has been generated from ${clazz.mixinName}
      abstract class ${clazz.factoryName} {
        static ${clazz.mixinType} make${clazz.typeArgsWithParens}(
          ${clazz.factoryParams}
        ) {
          return ${clazz.className}.make(
            ${clazz.constructorArgs}
          );
        }
      }
      abstract class ${clazz.baseClassName}${clazz.typeArgsWithParens} {
        const ${clazz.baseClassName}();

        ${clazz.copyWithSignature};
      }
      @immutable
      class ${clazz.className}${clazz.typeArgsWithParens}
          extends ${clazz.baseClassName}${clazz.typeArgsWithParens}
          with ${clazz.mixinName}${clazz.typeArgsWithParens}
      {
        ${clazz.fieldDeclarations}

        const ${clazz.className}.make(
          ${clazz.constructorParams}
        ) ${clazz.constructorAsserts}

        @override
        ${clazz.copyWithSignature} {
          return ${clazz.className}.make(
            ${clazz.copyWithArgs}
          );
        }

        ${clazz.config.genEqHashCode ? eqImpl(clazz.className, clazz.fieldNames) : ''}

        ${clazz.config.genEqHashCode ? hashCodeImpl(clazz.fieldNames) : ''}

        ${clazz.config.genToString ? toStringMethod : ''}
      }''';
    // print(code);
    return code;
  } on CodegenException catch (e) {
    e.generatorName = 'DataClass';
    rethrow;
  }
}