2024-06-26 14:45:54 -04:00
using dnlib.DotNet ;
2024-06-16 01:48:48 -04:00
using ReCodeIt.Models ;
using ReCodeIt.Utils ;
namespace ReCodeIt.ReMapper ;
internal static class RenameHelper
{
2024-06-16 03:43:00 -04:00
private static List < string > TokensToMatch = > DataProvider . Settings . AutoMapper . TokensToMatch ;
2024-06-16 01:48:48 -04:00
/// <summary>
/// Only used by the manual remapper, should probably be removed
/// </summary>
2024-06-26 14:45:54 -04:00
/// <param name="module"></param>
/// <param name="remap"></param>
/// <param name="direct"></param>
public static void RenameAll ( IEnumerable < TypeDef > types , RemapModel remap , bool direct = false )
2024-06-16 01:48:48 -04:00
{
// Rename all fields and properties first
2024-06-21 17:01:07 -04:00
if ( DataProvider . Settings . Remapper . MappingSettings . RenameFields )
{
2024-06-26 14:45:54 -04:00
RenameAllFields (
remap . TypePrimeCandidate . Name . String ,
remap . NewTypeName ,
types ) ;
2024-06-21 17:01:07 -04:00
}
if ( DataProvider . Settings . Remapper . MappingSettings . RenameProperties )
{
2024-06-26 14:45:54 -04:00
RenameAllProperties (
remap . TypePrimeCandidate . Name . String ,
remap . NewTypeName ,
types ) ;
2024-06-21 17:01:07 -04:00
}
2024-06-16 01:48:48 -04:00
2024-06-18 17:35:31 -04:00
if ( ! direct )
{
2024-06-26 14:45:54 -04:00
RenameType ( types , remap ) ;
2024-06-18 17:35:31 -04:00
}
2024-06-16 01:48:48 -04:00
2024-06-26 14:45:54 -04:00
Logger . Log ( $"{remap.TypePrimeCandidate.Name.String} Renamed." , ConsoleColor . Green ) ;
2024-06-16 01:48:48 -04:00
}
/// <summary>
/// Only used by the manual remapper, should probably be removed
/// </summary>
2024-06-26 14:45:54 -04:00
/// <param name="module"></param>
/// <param name="remap"></param>
/// <param name="type"></param>
public static void RenameAllDirect ( IEnumerable < TypeDef > types , RemapModel remap , TypeDef type )
2024-06-16 01:48:48 -04:00
{
2024-06-26 14:45:54 -04:00
RenameAll ( types , remap , true ) ;
2024-06-16 01:48:48 -04:00
}
/// <summary>
/// Rename all fields recursively, returns number of fields changed
/// </summary>
/// <param name="oldTypeName"></param>
/// <param name="newTypeName"></param>
/// <param name="typesToCheck"></param>
/// <returns></returns>
2024-06-26 14:45:54 -04:00
public static IEnumerable < TypeDef > RenameAllFields (
2024-06-16 01:48:48 -04:00
string oldTypeName ,
string newTypeName ,
2024-06-26 14:45:54 -04:00
IEnumerable < TypeDef > typesToCheck ,
2024-06-16 01:48:48 -04:00
int overAllCount = 0 )
{
foreach ( var type in typesToCheck )
{
2024-06-16 03:43:00 -04:00
var fields = type . Fields
. Where ( field = > field . Name . IsFieldOrPropNameInList ( TokensToMatch ) ) ;
if ( ! fields . Any ( ) ) { continue ; }
2024-06-16 01:48:48 -04:00
int fieldCount = 0 ;
2024-06-16 03:43:00 -04:00
foreach ( var field in fields )
2024-06-16 01:48:48 -04:00
{
2024-06-26 14:45:54 -04:00
if ( field . FieldType . TypeName = = oldTypeName )
2024-06-16 01:48:48 -04:00
{
2024-06-26 14:45:54 -04:00
var newFieldName = GetNewFieldName ( newTypeName , fieldCount ) ;
2024-06-16 01:48:48 -04:00
2024-06-16 03:43:00 -04:00
// Dont need to do extra work
2024-06-16 01:48:48 -04:00
if ( field . Name = = newFieldName ) { continue ; }
2024-06-26 14:45:54 -04:00
Logger . Log ( $"Renaming field on type {type.Name} named `{field.Name}` with type `{field.FieldType.TypeName}` to `{newFieldName}`" , ConsoleColor . Green ) ;
var oldName = field . Name . ToString ( ) ;
2024-06-16 01:48:48 -04:00
field . Name = newFieldName ;
2024-06-26 14:45:54 -04:00
UpdateTypeFieldMemberRefs ( type , field , oldName ) ;
UpdateAllTypeFieldMemberRefs ( typesToCheck , field , oldName ) ;
2024-06-16 01:48:48 -04:00
fieldCount + + ;
overAllCount + + ;
}
}
2024-06-26 14:45:54 -04:00
}
2024-06-16 01:48:48 -04:00
2024-06-26 14:45:54 -04:00
return typesToCheck ;
}
private static void UpdateAllTypeFieldMemberRefs ( IEnumerable < TypeDef > typesToCheck , FieldDef newDef , string oldName )
{
foreach ( var type in typesToCheck )
{
UpdateTypeFieldMemberRefs ( type , newDef , oldName ) ;
}
}
private static void UpdateTypeFieldMemberRefs ( TypeDef type , FieldDef newDef , string oldName )
{
foreach ( var method in type . Methods )
{
if ( ! method . HasBody ) continue ;
foreach ( var instr in method . Body . Instructions )
2024-06-16 01:48:48 -04:00
{
2024-06-26 14:45:54 -04:00
if ( instr . Operand is MemberRef memRef & & memRef . Name = = oldName )
{
//if (!memRef.Name.IsFieldOrPropNameInList(TokensToMatch)) continue;
Logger . Log ( $"Renaming MemRef in method {method.DeclaringType.Name}::{method.Name} from `{memRef.Name}` to `{newDef.Name}`" , ConsoleColor . Yellow ) ;
memRef . Name = newDef . Name ;
}
2024-06-16 01:48:48 -04:00
}
}
2024-06-26 14:45:54 -04:00
}
2024-06-16 01:48:48 -04:00
2024-06-26 14:45:54 -04:00
private static void RenameAllFieldRefsInMethods ( IEnumerable < TypeDef > typesToCheck , FieldDef newDef , string oldName )
{
foreach ( var type in typesToCheck )
{
foreach ( var method in type . Methods )
{
if ( ! method . HasBody ) continue ;
ChangeFieldNamesInMethods ( method , newDef , oldName ) ;
}
}
}
/// <summary>
/// Rename all field and member refs in a method
/// </summary>
/// <param name="method"></param>
/// <param name="newDef"></param>
/// <param name="oldName"></param>
private static void ChangeFieldNamesInMethods ( MethodDef method , FieldDef newDef , string oldName )
{
foreach ( var instr in method . Body . Instructions )
{
if ( instr . Operand is FieldDef fieldDef & & fieldDef . Name = = oldName )
{
if ( ! fieldDef . Name . IsFieldOrPropNameInList ( TokensToMatch ) ) continue ;
Logger . Log ( $"Renaming fieldDef in method {method.Name} from `{fieldDef.Name}` to `{newDef.Name}`" , ConsoleColor . Yellow ) ;
fieldDef . Name = newDef . Name ;
}
}
2024-06-16 01:48:48 -04:00
}
/// <summary>
/// Rename all properties recursively, returns number of fields changed
/// </summary>
/// <param name="oldTypeName"></param>
/// <param name="newTypeName"></param>
/// <param name="typesToCheck"></param>
/// <returns></returns>
public static int RenameAllProperties (
string oldTypeName ,
string newTypeName ,
2024-06-26 14:45:54 -04:00
IEnumerable < TypeDef > typesToCheck ,
2024-06-16 01:48:48 -04:00
int overAllCount = 0 )
{
foreach ( var type in typesToCheck )
{
2024-06-16 03:43:00 -04:00
var properties = type . Properties
. Where ( prop = > prop . Name . IsFieldOrPropNameInList ( TokensToMatch ) ) ;
2024-06-16 01:48:48 -04:00
2024-06-16 03:43:00 -04:00
if ( ! properties . Any ( ) ) { continue ; }
int propertyCount = 0 ;
foreach ( var property in properties )
2024-06-16 01:48:48 -04:00
{
2024-06-26 14:45:54 -04:00
if ( property . PropertySig . RetType . TypeName = = oldTypeName )
2024-06-16 01:48:48 -04:00
{
2024-06-16 03:43:00 -04:00
var newPropertyName = GetNewPropertyName ( newTypeName , propertyCount ) ;
// Dont need to do extra work
if ( property . Name = = newPropertyName ) { continue ; }
2024-06-16 01:48:48 -04:00
2024-06-26 14:45:54 -04:00
Logger . Log ( $"Renaming property on type {type.Name} named `{property.Name}` with type `{property.PropertySig.RetType.TypeName}` to `{newPropertyName}`" , ConsoleColor . Green ) ;
property . Name = new UTF8String ( newPropertyName ) ;
2024-06-16 01:48:48 -04:00
propertyCount + + ;
overAllCount + + ;
}
}
}
return overAllCount ;
}
2024-06-26 14:45:54 -04:00
public static string GetNewFieldName ( string NewName , int fieldCount = 0 )
2024-06-16 01:48:48 -04:00
{
string newFieldCount = fieldCount > 0 ? $"_{fieldCount}" : string . Empty ;
2024-06-26 14:45:54 -04:00
return $"{char.ToLower(NewName[0])}{NewName[1..]}{newFieldCount}" ;
2024-06-16 01:48:48 -04:00
}
public static string GetNewPropertyName ( string newName , int propertyCount = 0 )
{
return propertyCount > 0 ? $"{newName}_{propertyCount}" : newName ;
}
2024-06-18 17:35:31 -04:00
2024-06-26 14:45:54 -04:00
private static void RenameType ( IEnumerable < TypeDef > typesToCheck , RemapModel remap )
2024-06-18 17:35:31 -04:00
{
foreach ( var type in typesToCheck )
{
if ( type . HasNestedTypes )
{
2024-06-26 14:45:54 -04:00
RenameType ( type . NestedTypes , remap ) ;
2024-06-18 17:35:31 -04:00
}
2024-06-26 14:45:54 -04:00
if ( remap . TypePrimeCandidate . Name is null ) { continue ; }
2024-06-22 02:28:36 -04:00
2024-06-26 14:45:54 -04:00
if ( remap . SearchParams . IsNested is true & &
type . IsNested & & type . Name = = remap . TypePrimeCandidate . Name )
2024-06-22 02:28:36 -04:00
{
2024-06-26 14:45:54 -04:00
type . Name = remap . NewTypeName ;
2024-06-22 02:28:36 -04:00
}
2024-06-18 17:35:31 -04:00
2024-06-26 14:45:54 -04:00
if ( type . FullName = = remap . TypePrimeCandidate . Name )
2024-06-18 17:35:31 -04:00
{
2024-06-26 14:45:54 -04:00
type . Name = remap . NewTypeName ;
2024-06-18 17:35:31 -04:00
}
}
}
2024-06-16 01:48:48 -04:00
}