generate method

  1. @override
FutureOr<String> generate(
  1. LibraryReader library,
  2. BuildStep buildStep
)

Generates Dart code for an input Dart library.

May create additional outputs through the buildStep, but the 'primary' output is Dart code returned through the Future. If there is nothing to generate for this library may return null, or a Future that resolves to null or the empty string.

Implementation

@override
FutureOr<String> generate(LibraryReader library, BuildStep buildStep) async {
  final annotated = library.classes.where((el) => _hasStereotypeAnnotation(el) && (el.isExtendableOutside || el.isImplementableOutside || el.isMixableOutside) && !_hasInterceptableMixinOrSuper(el)).toList();
  if (annotated.isEmpty) return '';

  // read source to capture imports verbatim
  final imports = library.element.firstFragment.importedLibraries.map((i) => i.uri.toString()).toList();
  imports.addAll([
    'package:jetleaf_core/intercept.dart',
    'package:jetleaf_lang/lang.dart'
  ]);

  // collect all URIs we will need to import with aliases:
  // - the original library (we'll import by URI)
  // - every library that owns a referenced type (param types, return types, supertypes)
  final neededUris = <Uri>{library.element.uri};

  // accumulate types while scanning classes and supertypes
  for (final cls in annotated) {
    neededUris.addAll(_collectUrisForClass(cls));
  }

  // also ensure we include jetleaf intercept package
  final interceptUri = Uri.parse('package:jetleaf_core/intercept.dart');
  neededUris.add(interceptUri);
  neededUris.add(_INTERCEPT_URI);
  neededUris.add(_LANG_URI);

  // build alias map
  final aliasMap = <Uri, String>{};
  for (final uri in neededUris) {
    aliasMap[uri] = aliasForUri(uri);
  }

  // Begin building output
  final buffer = StringBuffer();
  writeGeneratedHeader(buffer, library.element.uri.toString());

  // print original source imports first to preserve local context
  writeGeneratedImports(buffer, imports.toMap((i) => i, (i) => []), aliased: false);

  // Add aliased imports for every neededUri (skip the current library import line since it's already present)
  for (final uri in neededUris) {
    final uriStr = uri.toString();
    // skip internal dart:_ URIs — they are internal to the SDK and cannot be imported by user code
    if (_isInternalSdkUri(uri)) {
      // ensure we still have an alias entry to avoid crashes, but do NOT emit an import
      continue;
    }
    final alias = aliasMap[uri]!;
    // avoid re-importing the current library if it's already in the file's original imports
    buffer.writeln("import '$uriStr' as $alias;");
  }

  buffer.writeln();

  // For each annotated class, generate proxy
  for (final cls in annotated) {
    _generateProxyForClass(buffer, cls, aliasMap, buildStep);
    buffer.writeln();
  }

  return buffer.toString();
}