purgeStaleCppSwiftRegistrations function

void purgeStaleCppSwiftRegistrations(
  1. List<ModuleInfo> cppModules, {
  2. String platform = 'ios',
  3. String baseDir = '.',
})

Removes stale <Module>Registry.register(...) calls from *Plugin.swift for modules that have been converted to NativeImpl.cpp (AppleNativeImpl.cpp).

C++ modules auto-register via __attribute__((constructor)) when the .dylib loads. No Swift Registry.register() call is needed or valid — the Registry class is not generated for CppImpl modules, so the call causes: "Cannot find <Module>Registry in scope"

This mirrors purgeStaleCppKotlinRegistrations on the Swift side.

Implementation

void purgeStaleCppSwiftRegistrations(
  List<ModuleInfo> cppModules, {
  String platform = 'ios',
  String baseDir = '.',
}) {
  if (cppModules.isEmpty) return;
  final platformDir = Directory(p.join(baseDir, platform));
  if (!platformDir.existsSync()) return;
  final pluginFiles = platformDir
      .listSync(recursive: true, followLinks: false)
      .whereType<File>()
      .where((f) => !f.path.contains('.symlinks'))
      .where((f) => f.path.endsWith('Plugin.swift'))
      .toList();
  if (pluginFiles.isEmpty) return;
  final pluginFile = pluginFiles.first;
  var content = pluginFile.readAsStringSync();
  bool modified = false;

  for (final m in cppModules) {
    // Match lines like:
    //   BenchmarkCppRegistry.register(BenchmarkCppModuleImpl())
    //   BenchmarkCppRegistry.register(BenchmarkCppImpl())
    // with optional leading whitespace.
    final stalePattern = RegExp(
      r'[ \t]*' +
          RegExp.escape('${m.module}Registry') +
          r'\.register\(.*\)[ \t]*\r?\n?',
    );
    if (stalePattern.hasMatch(content)) {
      content = content.replaceAll(stalePattern, '');
      modified = true;
    }
  }

  if (modified) pluginFile.writeAsStringSync(content);
}