0
0
mirror of https://github.com/sp-tarkov/assembly-tool.git synced 2025-02-13 09:30:46 -05:00

174 lines
5.4 KiB
C#
Raw Normal View History

using dnlib.DotNet;
2024-12-31 13:46:44 -05:00
using ReCodeItLib.Models;
using ReCodeItLib.Utils;
2024-06-16 01:48:48 -04:00
2024-12-31 13:46:44 -05:00
namespace ReCodeItLib.ReMapper;
2024-06-16 01:48:48 -04:00
internal class Renamer
2024-06-16 01:48:48 -04:00
{
2025-01-08 22:08:00 -05:00
private static List<string> TokensToMatch => DataProvider.Settings!.TypeNamesToMatch;
2024-06-16 03:43:00 -04:00
2024-06-16 01:48:48 -04:00
/// <summary>
/// Only used by the manual remapper, should probably be removed
/// </summary>
/// <param name="module"></param>
/// <param name="remap"></param>
/// <param name="direct"></param>
public void RenameAll(IEnumerable<TypeDef> types, RemapModel remap)
2024-06-16 01:48:48 -04:00
{
if (remap.TypePrimeCandidate is null) return;
// Rename all fields and properties first
RenameAllFields(
remap.TypePrimeCandidate.Name.String,
remap.NewTypeName,
types);
2024-06-21 17:01:07 -04:00
RenameAllProperties(
2025-01-11 06:18:08 -05:00
remap.TypePrimeCandidate!.Name.String,
remap.NewTypeName,
types);
2024-06-16 01:48:48 -04:00
FixMethods(types, remap);
2025-01-11 06:18:08 -05:00
remap.TypePrimeCandidate.Name = remap.NewTypeName;
2024-12-31 00:21:32 -05:00
}
private static void FixMethods(
2024-12-31 00:21:32 -05:00
IEnumerable<TypeDef> typesToCheck,
RemapModel remap)
{
foreach (var type in typesToCheck)
2024-06-18 17:35:31 -04:00
{
2025-01-10 06:35:51 -05:00
List<MethodDef> methodsToFix = [];
methodsToFix.AddRange(
from method in type.Methods where method.Name.StartsWith(remap.TypePrimeCandidate!.Name.String)
let splitName = method.Name.String.Split(".") where splitName.Length != 1 select method);
2024-06-16 01:48:48 -04:00
2025-01-10 06:35:51 -05:00
foreach (var method in methodsToFix)
2024-12-31 00:21:32 -05:00
{
var name = method.Name.String.Split(".");
2025-01-06 17:22:04 -05:00
2025-01-10 06:35:51 -05:00
if (methodsToFix.Count(m => m.Name.String.EndsWith(name[1])) > 1)
2025-01-06 17:22:04 -05:00
continue;
method.Name = name[1];
2024-12-31 00:21:32 -05:00
}
}
2024-06-16 01:48:48 -04:00
}
2024-12-30 13:20:44 -05:00
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>
2024-12-31 03:13:29 -05:00
private static void RenameAllFields(
2024-06-16 01:48:48 -04:00
string oldTypeName,
string newTypeName,
2024-12-31 00:21:32 -05:00
IEnumerable<TypeDef> typesToCheck)
2024-06-16 01:48:48 -04:00
{
2025-01-11 06:18:08 -05:00
var typeDefs = typesToCheck as TypeDef[] ?? typesToCheck.ToArray();
foreach (var type in typeDefs)
2024-06-16 01:48:48 -04:00
{
2024-06-16 03:43:00 -04:00
var fields = type.Fields
2024-12-31 03:13:29 -05:00
.Where(field => field.Name.IsFieldOrPropNameInList(TokensToMatch!));
2024-06-16 03:43:00 -04:00
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
{
if (field.FieldType.TypeName == oldTypeName)
2024-06-16 01:48:48 -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-12-29 13:38:04 -05:00
var oldName = field.Name.ToString();
2024-06-16 01:48:48 -04:00
field.Name = newFieldName;
2025-01-11 06:18:08 -05:00
UpdateAllTypeFieldMemberRefs(typeDefs, field, oldName);
2024-06-16 01:48:48 -04:00
fieldCount++;
}
}
}
}
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
{
if (instr.Operand is MemberRef memRef && memRef.Name == oldName)
{
memRef.Name = newDef.Name;
}
2024-06-16 01:48:48 -04:00
}
}
}
2024-12-30 13:20:44 -05:00
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>
2024-12-31 03:13:29 -05:00
private static void RenameAllProperties(
2024-06-16 01:48:48 -04:00
string oldTypeName,
string newTypeName,
2024-12-31 00:21:32 -05:00
IEnumerable<TypeDef> typesToCheck)
2024-06-16 01:48:48 -04:00
{
foreach (var type in typesToCheck)
{
2024-06-16 03:43:00 -04:00
var properties = type.Properties
2024-12-31 03:13:29 -05:00
.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
{
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-12-29 13:38:04 -05:00
property.Name = new UTF8String(newPropertyName);
2024-06-16 01:48:48 -04:00
propertyCount++;
}
}
}
}
2024-12-31 00:21:32 -05:00
private static string GetNewFieldName(string NewName, int fieldCount = 0)
2024-06-16 01:48:48 -04:00
{
string newFieldCount = fieldCount > 0 ? $"_{fieldCount}" : string.Empty;
return $"{char.ToLower(NewName[0])}{NewName[1..]}{newFieldCount}";
2024-06-16 01:48:48 -04:00
}
2024-12-31 00:21:32 -05:00
private static string GetNewPropertyName(string newName, int propertyCount = 0)
2024-06-16 01:48:48 -04:00
{
return propertyCount > 0 ? $"{newName}_{propertyCount}" : newName;
}
}