fixAll function
Future<FixSummary>
fixAll(
- String root, {
- bool apply = true,
- int maxRounds = 10,
- DiagnosticSource analyze = analyzeWithDart,
- void onFix(
- AppliedFix fix
Applies every view_model_lint quick fix in root, round by round.
Fixes are computed from one analysis of the package. Edits that would touch the same text, or insert at the same position, are deferred to the next round so each fix sees the code the previous ones produced.
Implementation
Future<FixSummary> fixAll(
String root, {
bool apply = true,
int maxRounds = 10,
DiagnosticSource analyze = analyzeWithDart,
void Function(AppliedFix fix)? onFix,
}) async {
final kinds = {
for (final kind in viewModelFixes.keys) viewModelCodeName(kind): kind,
};
final fixes = <AppliedFix>[];
var diagnostics = await analyze(root);
for (var round = 0; round < maxRounds; round++) {
final fixable = diagnostics.where((d) => kinds.containsKey(d.code));
final byFile = <String, List<ReportedDiagnostic>>{};
for (final diagnostic in fixable) {
byFile.putIfAbsent(diagnostic.path, () => []).add(diagnostic);
}
if (byFile.isEmpty) break;
final collection = AnalysisContextCollection(includedPaths: [root]);
var changed = false;
for (final MapEntry(key: path, value: found) in byFile.entries) {
final AnalysisSession session;
try {
session = collection.contextFor(path).currentSession;
} on StateError {
continue; // Reported outside the analyzed package.
}
final unit = await session.getResolvedUnit(path);
if (unit is! ResolvedUnitResult) continue;
final library = await session.getResolvedLibraryByElement(
unit.libraryElement,
);
if (library is! ResolvedLibraryResult) continue;
found.sort((a, b) => a.offset.compareTo(b.offset));
final accepted = <SourceEdit>[];
for (final diagnostic in found) {
final fix = await _computeFix(unit, library, diagnostic, kinds);
if (fix == null || _overlaps(fix.$1, accepted)) continue;
accepted.addAll(fix.$1);
final line = unit.lineInfo.getLocation(diagnostic.offset).lineNumber;
final applied = AppliedFix(path, line, diagnostic.code, fix.$2);
fixes.add(applied);
onFix?.call(applied);
}
if (accepted.isEmpty) continue;
accepted.sort((a, b) => b.offset.compareTo(a.offset));
if (apply) {
File(
path,
).writeAsStringSync(SourceEdit.applySequence(unit.content, accepted));
}
changed = true;
}
await collection.dispose();
if (!apply || !changed) break;
diagnostics = await analyze(root);
}
return FixSummary(fixes, [
for (final diagnostic in diagnostics)
if (diagnostic.code.startsWith('view_model_')) diagnostic,
]);
}