import 'dart:collection'; import 'dart:io'; void main() async { final List dartFiles = listDartFiles(); final UnmodifiableListView unmodifiableListView = UnmodifiableListView( [ MigrationBlocFreezedHandler(), MigrationModelFreezedHandler(), ], ); fileLoop: for (final file in dartFiles) { for (final handler in unmodifiableListView) { if (file.path.contains(handler.shouldContain)) { await handler.migrate(file); continue fileLoop; } } } } List listDartFiles() { final directory = Directory('lib'); final fileList = directory.listSync(recursive: true); final regexOnlyDartFiles = RegExp(r'(? dartFiles = []; for (final file in fileList) { if (regexOnlyDartFiles.hasMatch(file.path)) { dartFiles.add(file as File); } } return dartFiles; } sealed class MigrationHandler { Future migrate(File file) async { shouldChangeNextLine = false; await migrationLogic(file); } bool freezedClassMigration(String line) { final isContainsFreezedAnnotation = line.contains('@freezed'); shouldChangeNextLine = isContainsFreezedAnnotation; return isContainsFreezedAnnotation; } bool shouldChangeNextLine = false; Future migrationLogic(File file); String get shouldContain; } class MigrationBlocFreezedHandler extends MigrationHandler { @override String get shouldContain => '_bloc.dart'; @override Future migrationLogic(File file) async { final lines = file.readAsLinesSync(); file.writeAsStringSync('', mode: FileMode.write); String className = ''; for (final line in lines) { if (shouldChangeNextLine && line.contains('sealed')) { className = line.split(' ')[2]; file.writeAsStringSync('$line\n', mode: FileMode.append); shouldChangeNextLine = false; continue; } else if (shouldChangeNextLine && !line.contains('sealed')) { className = line.split(' ')[1]; file.writeAsStringSync('sealed $line\n', mode: FileMode.append); shouldChangeNextLine = false; } else if (freezedClassMigration(line)) { file.writeAsStringSync('$line\n', mode: FileMode.append); continue; } else if (isOneLineFactoryEvent(line)) { appendEventKeyword(line, file, className); continue; } else if (isOneLineFactoryState(line)) { appendStateKeyword(line, file, className); continue; } else { file.writeAsStringSync('$line\n', mode: FileMode.append); continue; } } } Future appendStateKeyword(String line, File file, String className) async { final classNameWithoutEventKeyword = className.replaceAll('State', ''); final eventName = line.split('_')[1].replaceAll('State', '').replaceAll(';', ''); final fullFreezedEventName = '$classNameWithoutEventKeyword${eventName}State'; file.writeAsStringSync( '${line.replaceAll('_$eventName', fullFreezedEventName).replaceAll('StateState', 'State').replaceAll(';', '')};\n', mode: FileMode.append, ); } Future appendEventKeyword(String line, File file, String className) async { final classNameWithoutEventKeyword = className.replaceAll('Event', ''); final eventName = line.split('_')[1].replaceAll('Event', '').replaceAll(';', ''); final fullFreezedEventName = '$classNameWithoutEventKeyword${eventName}Event'; file.writeAsStringSync( '${line.replaceAll('_$eventName', fullFreezedEventName).replaceAll('EventEvent', 'Event').replaceAll(';', '')};\n', mode: FileMode.append, ); } bool isOneLineFactoryEvent(String line) { return line.contains('const factory') && line.contains('_') && line.contains('Event'); } bool isOneLineFactoryState(String line) { return line.contains('const factory') && line.contains('_') && line.contains('State'); } } class MigrationModelFreezedHandler extends MigrationHandler { @override String get shouldContain => '.dart'; @override Future migrationLogic(File file) async { final lines = file.readAsLinesSync(); file.writeAsStringSync('', mode: FileMode.write); for (final line in lines) { /// Skipping if (line.contains("import 'package:flutter_bloc/flutter_bloc.dart';'")) { break; } if (shouldChangeNextLine && line.contains('abstract') || line.contains('sealed')) { file.writeAsStringSync('$line\n', mode: FileMode.append); shouldChangeNextLine = false; continue; } else if (shouldChangeNextLine && !line.contains('abstract')) { file.writeAsStringSync('abstract $line\n', mode: FileMode.append); shouldChangeNextLine = false; } else if (freezedClassMigration(line)) { file.writeAsStringSync('$line\n', mode: FileMode.append); continue; } else { file.writeAsStringSync('$line\n', mode: FileMode.append); continue; } } } }