generateForAnnotatedElement method

  1. @override
Future<String> generateForAnnotatedElement(
  1. Element element,
  2. ConstantReader annotation,
  3. 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 {
  Element enviedEl = element;
  if (enviedEl is! ClassElement) {
    throw InvalidGenerationSourceError(
      '`@Envied` can only be used on classes.',
      element: enviedEl,
    );
  }

  final config = Envied(
    path: annotation.read('path').literalValue as String?,
    requireEnvFile:
        annotation.read('requireEnvFile').literalValue as bool? ?? false,
    name: annotation.read('name').literalValue as String?,
    obfuscate: annotation.read('obfuscate').literalValue as bool,
  );

  final envs = await loadEnvs(config.path, (error) {
    if (config.requireEnvFile) {
      throw InvalidGenerationSourceError(
        error,
        element: enviedEl,
      );
    }
  });

  TypeChecker enviedFieldChecker = TypeChecker.fromRuntime(EnviedField);

  final lines = enviedEl.fields.map((fieldEl) {
    if (enviedFieldChecker.hasAnnotationOf(fieldEl)) {
      DartObject? dartObject = enviedFieldChecker.firstAnnotationOf(fieldEl);
      ConstantReader reader = ConstantReader(dartObject);

      String varName =
          reader.read('varName').literalValue as String? ?? fieldEl.name;

      Object? defaultValue = reader.read('defaultValue').literalValue;

      String? varValue;
      if (envs.containsKey(varName)) {
        varValue = envs[varName];
      } else if (Platform.environment.containsKey(varName)) {
        varValue = Platform.environment[varName];
      } else {
        if (defaultValue != null) {
          varValue = defaultValue.toString();
        }
      }

      final bool obfuscate =
          reader.read('obfuscate').literalValue as bool? ?? config.obfuscate;

      return (obfuscate ? generateLineEncrypted : generateLine)(
        fieldEl,
        varValue,
      );
    } else {
      return '';
    }
  });

  return '''
  class _${config.name ?? enviedEl.name} {
    ${lines.toList().join()}
  }
  ''';
}