addImportAndChangesInFile method

Future<void> addImportAndChangesInFile({
  1. required String filePath,
  2. required List<String> importStatements,
  3. required List<String> methodCalls,
})

Implementation

Future<void> addImportAndChangesInFile({
  required String filePath,
  required List<String> importStatements,
  required List<String> methodCalls,
}) async {
  final file = File(filePath);
  final lines = await file.readAsLines();

  // Scan the WHOLE file for the last import line. The previous version
  // `break`-ed at the first non-import line, so a leading comment, blank
  // line or `library`/`part` directive left lastImportIndex = -1 and the
  // entire block (imports AND method calls) was silently skipped.
  int lastImportIndex = -1;
  for (int i = 0; i < lines.length; i++) {
    if (lines[i].startsWith("$kImport ")) {
      lastImportIndex = i;
    }
  }

  // Skip imports the file already has. The comparison runs against a
  // whitespace-collapsed view of the file for the same reason as `addImport`:
  // `dart format` may have wrapped or re-indented an existing import, and a
  // plain line match would then miss it and insert a duplicate. Without this,
  // the DI files gained one extra `injection_container.dart` import per
  // generated feature.
  final existing = StringBuffer(collapseWhitespace(lines.join(' ')));
  final List<String> newImports = [];
  for (final importStatement in importStatements) {
    final normalized = collapseWhitespace(importStatement);
    if (existing.toString().contains(normalized)) {
      continue;
    }
    newImports.add(importStatement);
    existing.write(' $normalized');
  }

  if (newImports.isNotEmpty) {
    // Insert after the last import, or at the top when there are none.
    lines.insertAll(lastImportIndex + 1, newImports);
  }

  int completionIndex = -1;
  for (int i = 0; i < lines.length; i++) {
    if (lines[i].trim() == '}') {
      completionIndex = i;
    }
  }

  if (completionIndex != -1) {
    if (methodCalls.isNotEmpty) {
      lines.insertAll(completionIndex, methodCalls);
    }
    await file.writeAsString(lines.join('\n'));
  }
}