emitStResolvedExtension function

void emitStResolvedExtension(
  1. StringBuffer buf, {
  2. required String extensionName,
  3. List<STExtraIr> extras = const [],
  4. List<String> extraColors = const [],
  5. List<String> extraComponents = const [],
})

Implementation

void emitStResolvedExtension(
  StringBuffer buf, {
  required String extensionName,
  List<STExtraIr> extras = const [],
  List<String> extraColors = const [],
  List<String> extraComponents = const [],
}) {
  final extraNames = extras.map((e) => e.name).toSet();
  final containers = [
    for (final name in extraComponents)
      if (!extraNames.contains(name))
        STExtraIr(name: name, kind: STIrKind.container),
  ];
  if (extras.isEmpty && extraColors.isEmpty && containers.isEmpty) return;

  final used = <String>{};
  buf.writeln('extension $extensionName on STResolved {');

  if (extraColors.isNotEmpty) {
    buf.writeln('  // Extra colors — Color (Container, Text, …)');
    for (final name in extraColors) {
      final getter = _claim(used, stColorGetterName(name), name);
      buf.writeln("  Color get $getter => color('${_escape(name)}');");
    }
  }

  void claimStyle(String getter, String suffix) {
    final styled = '$getter$suffix';
    if (!used.add(styled)) {
      throw FormatException('Generated getter "$styled" is used twice.');
    }
  }

  var section = '';
  void kindComment(String label) {
    if (section == label) return;
    section = label;
    buf.writeln('  // $label');
  }

  for (final extra in extras) {
    final getter = _claim(
      used,
      stExtraGetterName(extra.name, extra.kind),
      extra.name,
    );
    final escaped = _escape(extra.name);
    switch (extra.kind) {
      case STIrKind.button:
        kindComment('Buttons — ButtonStyle (ElevatedButton, FilledButton, …)');
        claimStyle(getter, 'Style');
        buf.writeln(
          "  STResolvedComponent get $getter => extraButton('$escaped');",
        );
        buf.writeln(
          '  ButtonStyle get ${getter}Style => $getter.toButtonStyle();',
        );
      case STIrKind.card:
        kindComment('Cards — BoxDecoration / fill Color');
        claimStyle(getter, 'Decoration');
        claimStyle(getter, 'Color');
        buf.writeln(
          "  STResolvedComponent get $getter => extraCard('$escaped');",
        );
        buf.writeln(
          '  BoxDecoration get ${getter}Decoration => $getter.toBoxDecoration();',
        );
        buf.writeln('  Color? get ${getter}Color => $getter.fill;');
      case STIrKind.container:
        kindComment('Containers — BoxDecoration / fill Color');
        claimStyle(getter, 'Decoration');
        claimStyle(getter, 'Color');
        buf.writeln(
          "  STResolvedComponent get $getter => extraContainer('$escaped');",
        );
        buf.writeln(
          '  BoxDecoration get ${getter}Decoration => $getter.toBoxDecoration();',
        );
        buf.writeln('  Color? get ${getter}Color => $getter.fill;');
      case STIrKind.text:
        kindComment('Text — TextStyle');
        buf.writeln("  TextStyle get $getter => extraText('$escaped');");
    }
  }

  if (containers.isNotEmpty) {
    kindComment('Containers — BoxDecoration / fill Color');
  }

  for (final extra in containers) {
    final getter = _claim(
      used,
      stExtraGetterName(extra.name, STIrKind.container),
      extra.name,
    );
    claimStyle(getter, 'Decoration');
    claimStyle(getter, 'Color');
    final escaped = _escape(extra.name);
    buf.writeln("  STResolvedComponent get $getter => container('$escaped');");
    buf.writeln(
      '  BoxDecoration get ${getter}Decoration => $getter.toBoxDecoration();',
    );
    buf.writeln('  Color? get ${getter}Color => $getter.fill;');
  }

  buf.writeln('}');
}