Skip to content

Instantly share code, notes, and snippets.

@alexcmgit
Created November 3, 2021 07:44
Show Gist options
  • Save alexcmgit/a56f1815977ee29c6b621f11e4e60758 to your computer and use it in GitHub Desktop.
Save alexcmgit/a56f1815977ee29c6b621f11e4e60758 to your computer and use it in GitHub Desktop.
Fix some Dart analyzer errors, save your work before using this script
import 'dart:io';
import 'package:equatable/equatable.dart';
const kPreferConstConstructors = 'prefer_const_constructors';
const kUnnecessaryConst = 'unnecessary_const';
const kPreferConstDeclarations = 'prefer_const_declarations';
Future<void> main() async {
final result = await Process.run('dart', ['analyze']);
final raw = result.stdout as String;
final supportedFixes = [
kPreferConstConstructors,
kUnnecessaryConst,
kPreferConstDeclarations,
];
final errors = raw
.split('\n')
.map((error) => error.trim().replaceAll(r' *', ' ').replaceAll(r'\', '/'))
.where((error) => error.startsWith('info') || error.startsWith('error'))
.map((error) {
final parts = error.split(' - ');
final type = parts[0],
location = parts[1].split(':'),
description = parts[2],
code = parts[3];
final path = location[0], line = location[1], column = location[2];
return StaticError(
line: int.parse(line),
column: int.parse(column),
description: description,
code: code,
type: type,
path: path,
);
}).where(
(error) => error.type == 'info' && supportedFixes.contains(error.code),
);
if (errors.isEmpty) return;
final files = <String, Map<int, StaticError>>{};
for (final error in errors) {
files[error.path] ??= {};
files[error.path]![error.line] = error;
}
for (final path in files.keys) {
final file = File(path);
final lines = file.readAsLinesSync();
for (final line in files[path]!.keys) {
final error = files[path]![line]!;
final contents = _errorHandler(error, lines);
file.writeAsStringSync(contents);
}
}
if (errors.isNotEmpty) return main();
}
String _errorHandler(StaticError error, List<String> lines) {
switch (error.code) {
case kPreferConstConstructors:
return _handleConstConstructorsInfo(error, lines);
case kUnnecessaryConst:
return _handleUnnecessaryConstInfo(error, lines);
case kPreferConstDeclarations:
return _handlePreferConstDeclarationsInfo(error, lines);
}
throw UnsupportedError('Got invalid error code: ${error.code}');
}
String _handleConstConstructorsInfo(StaticError error, List<String> lines) {
final line = error.line;
final newLine = lines[line - 1]
.replaceRange(error.column - 1, error.column - 1, 'const ');
lines[error.line - 1] = newLine;
final newFile = lines.join('\n');
return newFile;
}
String _handleUnnecessaryConstInfo(StaticError error, List<String> lines) {
final line = error.line;
final newLine = lines[line - 1].replaceFirst('const ', '',
lines[line - 1].lastIndexOf('const').clamp(0, lines[line - 1].length));
lines[error.line - 1] = newLine;
final newFile = lines.join('\n');
return newFile;
}
String _handlePreferConstDeclarationsInfo(
StaticError error, List<String> lines) {
final line = error.line;
final newLine =
lines[line - 1].replaceAll('const ', '').replaceAll('final', 'const');
lines[error.line - 1] = newLine;
final newFile = lines.join('\n');
return newFile;
}
class StaticError extends Equatable {
final int line;
final int column;
final String description;
final String code;
final String type;
final String path;
const StaticError({
required this.code,
required this.type,
required this.line,
required this.column,
required this.description,
required this.path,
});
@override
String toString() => '$type, $path:$line:$column, $description, $code';
@override
List<Object> get props => [path, line];
}
@alexcmgit
Copy link
Author

Usage: run dart apply.dart in the root project

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment