using Mono.Cecil; using Mono.Collections.Generic; using ReCodeIt.Models; using ReCodeIt.Utils; using ReCodeItLib.Utils; namespace ReCodeIt.ReMapper; internal static class RenameHelper { private static List TokensToMatch => DataProvider.Settings.AutoMapper.TokensToMatch; /// /// Only used by the manual remapper, should probably be removed /// /// public static void RenameAll(ScoringModel score) { var types = DataProvider.ModuleDefinition.Types; // Rename all fields and properties first RenameAllFields(score.Definition.Name, score.ReMap.NewTypeName, types); RenameAllProperties(score.Definition.Name, score.ReMap.NewTypeName, types); score.Definition.Name = score.ProposedNewName; Logger.Log($"{score.Definition.Name} Renamed.", ConsoleColor.Green); } /// /// Only used by the manual remapper, should probably be removed /// /// public static void RenameAllDirect(RemapModel remap, TypeDefinition type) { var directRename = new ScoringModel(); directRename.Definition = type; directRename.ReMap = remap; RenameAll(directRename); } /// /// Rename all fields recursively, returns number of fields changed /// /// /// /// /// public static int RenameAllFields( string oldTypeName, string newTypeName, Collection typesToCheck, int overAllCount = 0) { foreach (var type in typesToCheck) { var fields = type.Fields .Where(field => field.Name.IsFieldOrPropNameInList(TokensToMatch)); if (!fields.Any()) { continue; } int fieldCount = 0; foreach (var field in fields) { if (field.FieldType.Name == oldTypeName) { var newFieldName = GetNewFieldName(newTypeName, field.IsPrivate, fieldCount); // Dont need to do extra work if (field.Name == newFieldName) { continue; } Logger.Log($"Renaming original field type name: `{field.FieldType.Name}` with name `{field.Name}` to `{newFieldName}`", ConsoleColor.Green); field.Name = newFieldName; fieldCount++; overAllCount++; } } if (type.HasNestedTypes) { RenameAllFields(oldTypeName, newTypeName, type.NestedTypes, overAllCount); } } return overAllCount; } /// /// Rename all properties recursively, returns number of fields changed /// /// /// /// /// public static int RenameAllProperties( string oldTypeName, string newTypeName, Collection typesToCheck, int overAllCount = 0) { foreach (var type in typesToCheck) { var properties = type.Properties .Where(prop => prop.Name.IsFieldOrPropNameInList(TokensToMatch)); if (!properties.Any()) { continue; } int propertyCount = 0; foreach (var property in properties) { if (property.PropertyType.Name == oldTypeName) { var newPropertyName = GetNewPropertyName(newTypeName, propertyCount); // Dont need to do extra work if (property.Name == newPropertyName) { continue; } Logger.Log($"Renaming original property type name: `{property.PropertyType.Name}` with name `{property.Name}` to `{newPropertyName}`", ConsoleColor.Green); property.Name = newPropertyName; propertyCount++; overAllCount++; } } if (type.HasNestedTypes) { RenameAllProperties(oldTypeName, newTypeName, type.NestedTypes, overAllCount); } } return overAllCount; } public static string GetNewFieldName(string NewName, bool isPrivate, int fieldCount = 0) { var discard = isPrivate ? "_" : ""; string newFieldCount = fieldCount > 0 ? $"_{fieldCount}" : string.Empty; return $"{discard}{char.ToLower(NewName[0])}{NewName[1..]}{newFieldCount}"; } public static string GetNewPropertyName(string newName, int propertyCount = 0) { return propertyCount > 0 ? $"{newName}_{propertyCount}" : newName; } }