AutoMapper field and property handling
This commit is contained in:
parent
443530d79a
commit
802bacadce
@ -1,5 +1,7 @@
|
||||
using Mono.Cecil;
|
||||
using Mono.Collections.Generic;
|
||||
using ReCodeIt.Models;
|
||||
using ReCodeIt.ReMapper;
|
||||
using ReCodeIt.Utils;
|
||||
using ReCodeItLib.Utils;
|
||||
|
||||
@ -16,6 +18,9 @@ public class ReCodeItAutoMapper
|
||||
private static bool Error { get; set; } = false;
|
||||
private int FailureCount { get; set; } = 0;
|
||||
|
||||
private int TotalFieldRenameCount { get; set; } = 0;
|
||||
private int TotalPropertyRenameCount { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Start the automapping process
|
||||
/// </summary>
|
||||
@ -30,6 +35,8 @@ public class ReCodeItAutoMapper
|
||||
|
||||
Error = false;
|
||||
FailureCount = 0;
|
||||
TotalFieldRenameCount = 0;
|
||||
TotalPropertyRenameCount = 0;
|
||||
|
||||
FindCompilerGeneratedObjects(DataProvider.ModuleDefinition.Types);
|
||||
|
||||
@ -56,7 +63,7 @@ public class ReCodeItAutoMapper
|
||||
/// Finds any compiler generated code so we can ignore it, its mostly LINQ garbage
|
||||
/// </summary>
|
||||
/// <param name="types"></param>
|
||||
private void FindCompilerGeneratedObjects(Mono.Collections.Generic.Collection<TypeDefinition> types)
|
||||
private void FindCompilerGeneratedObjects(Collection<TypeDefinition> types)
|
||||
{
|
||||
foreach (var typeDefinition in types)
|
||||
{
|
||||
@ -117,12 +124,17 @@ public class ReCodeItAutoMapper
|
||||
{
|
||||
//Logger.Log($"Collecting Field: OriginalTypeRef: {field.FieldType.Name.TrimAfterSpecialChar()} Field Name: {field.Name}");
|
||||
|
||||
var typeDef = field.FieldType.Resolve();
|
||||
|
||||
// Dont rename things we cant resolve
|
||||
if (typeDef is null) { continue; }
|
||||
|
||||
fieldsWithTypes.Add(new MappingPair(
|
||||
field.FieldType,
|
||||
typeDef,
|
||||
field.Name,
|
||||
field.FieldType.Name.Contains("Interface"),
|
||||
field.FieldType.Name.Contains("Struct"),
|
||||
field.FieldType.IsGenericInstance || field.FieldType.IsArray));
|
||||
field.IsPublic));
|
||||
}
|
||||
|
||||
return fieldsWithTypes;
|
||||
@ -167,13 +179,17 @@ public class ReCodeItAutoMapper
|
||||
{
|
||||
//Logger.Log($"Collecting Property: OriginalTypeRef: {property.PropertyType.Name.TrimAfterSpecialChar()} Field Name: {property.Name}");
|
||||
|
||||
;
|
||||
var typeDef = property.PropertyType.Resolve();
|
||||
|
||||
// Dont rename things we cant resolve
|
||||
if (typeDef is null) { continue; }
|
||||
|
||||
propertiesWithTypes.Add(new MappingPair(
|
||||
property.PropertyType,
|
||||
typeDef,
|
||||
property.Name,
|
||||
property.PropertyType.Name.Contains("Interface"),
|
||||
property.PropertyType.Name.Contains("Struct")));
|
||||
property.PropertyType.Name.Contains("Struct"),
|
||||
true));
|
||||
}
|
||||
|
||||
return propertiesWithTypes;
|
||||
@ -194,7 +210,7 @@ public class ReCodeItAutoMapper
|
||||
// pair.OriginalTypeRef.Name is the property OriginalTypeRef name `Class1202` and token
|
||||
// is start identifer we are looking for `GClass`
|
||||
.Where(pair => Settings.TokensToMatch
|
||||
.Any(token => pair.OriginalTypeRef.Name.StartsWith(token)))
|
||||
.Any(token => pair.OriginalTypeDefinition.Name.StartsWith(token)))
|
||||
|
||||
// Filter out anything that has the same name as the type, we cant remap those
|
||||
.Where(pair => !Settings.TokensToMatch
|
||||
@ -210,7 +226,7 @@ public class ReCodeItAutoMapper
|
||||
.Where(pair => !pair.Name.ToCharArray().Contains('<'))
|
||||
|
||||
// We only want types once, so make it unique
|
||||
.GroupBy(pair => pair.OriginalTypeRef.FullName)
|
||||
.GroupBy(pair => pair.OriginalTypeDefinition.FullName)
|
||||
.Select(group => group.First())
|
||||
.GroupBy(pair => pair.Name)
|
||||
.Select(group => group.First())
|
||||
@ -245,7 +261,7 @@ public class ReCodeItAutoMapper
|
||||
{
|
||||
pair.Name = string.Concat("I", pair.Name.AsSpan(0));
|
||||
}
|
||||
|
||||
/*
|
||||
// Try and remove any trailing 's' that exist
|
||||
if (pair.WasCollection)
|
||||
{
|
||||
@ -254,7 +270,7 @@ public class ReCodeItAutoMapper
|
||||
pair.Name = pair.Name.Substring(0, pair.Name.Length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
// If its not an interface, its a struct or class
|
||||
switch (pair.IsStruct)
|
||||
{
|
||||
@ -268,9 +284,8 @@ public class ReCodeItAutoMapper
|
||||
}
|
||||
|
||||
Logger.Log($"------------------------------------------------------------------------");
|
||||
Logger.Log($"Original Name: {pair.OriginalFullName} : Sanitized Name: {pair.Name}");
|
||||
Logger.Log($"Original Name: {pair.OriginalTypeDefinition.FullName} : Sanitized Name: {pair.Name}");
|
||||
Logger.Log($"Matched From Name: {pair.OriginalPropOrFieldName}");
|
||||
Logger.Log($"Matched From Collection: {pair.WasCollection}");
|
||||
Logger.Log($"IsInterface: {pair.IsInterface}");
|
||||
Logger.Log($"IsStruct: {pair.IsStruct}");
|
||||
Logger.Log($"------------------------------------------------------------------------");
|
||||
@ -284,6 +299,7 @@ public class ReCodeItAutoMapper
|
||||
/// </summary>
|
||||
private void StartRenameProcess()
|
||||
{
|
||||
// Gather up any matches we have
|
||||
foreach (var type in DataProvider.ModuleDefinition.Types.ToArray())
|
||||
{
|
||||
foreach (var pair in MappingPairs.ToArray())
|
||||
@ -292,17 +308,33 @@ public class ReCodeItAutoMapper
|
||||
}
|
||||
}
|
||||
|
||||
// Rename Types to matched types
|
||||
foreach (var pair in MappingPairs)
|
||||
{
|
||||
if (pair.NewTypeRef != null)
|
||||
{
|
||||
Logger.Log($"------------------------------------------------------------------------", ConsoleColor.Green);
|
||||
Logger.Log($"Renaming: {pair.OriginalTypeDefinition.Name} to {pair.Name}", ConsoleColor.Green);
|
||||
|
||||
var fieldCount = RenameHelper.RenameAllFields(
|
||||
pair.OriginalTypeDefinition.Name,
|
||||
pair.Name,
|
||||
DataProvider.ModuleDefinition.Types);
|
||||
|
||||
var propCount = RenameHelper.RenameAllProperties(
|
||||
pair.OriginalTypeDefinition.Name,
|
||||
pair.Name,
|
||||
DataProvider.ModuleDefinition.Types);
|
||||
|
||||
TotalFieldRenameCount += fieldCount;
|
||||
TotalPropertyRenameCount += propCount;
|
||||
|
||||
Logger.Log($"Renamed: {fieldCount} fields", ConsoleColor.Green);
|
||||
Logger.Log($"Renamed: {propCount} properties", ConsoleColor.Green);
|
||||
Logger.Log($"------------------------------------------------------------------------", ConsoleColor.Green);
|
||||
|
||||
pair.NewTypeRef.Name = pair.Name;
|
||||
pair.HasBeenRenamed = true;
|
||||
|
||||
Logger.Log($"------------------------------------------------------------------------", ConsoleColor.Green);
|
||||
Logger.Log($"Renamed: {pair.OriginalShortName} to {pair.Name}", ConsoleColor.Green);
|
||||
Logger.Log($"Original Full Name: {pair.OriginalFullName}", ConsoleColor.Green);
|
||||
Logger.Log($"------------------------------------------------------------------------", ConsoleColor.Green);
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,8 +344,7 @@ public class ReCodeItAutoMapper
|
||||
if (!pair.HasBeenRenamed)
|
||||
{
|
||||
Logger.Log($"------------------------------------------------------------------------", ConsoleColor.Red);
|
||||
Logger.Log($"Renaming: {pair.OriginalTypeRef.Name} to {pair.Name} has failed", ConsoleColor.Red);
|
||||
Logger.Log($"Matched From Collection: {pair.WasCollection}", ConsoleColor.Red);
|
||||
Logger.Log($"Renaming: {pair.OriginalTypeDefinition.Name} to {pair.Name} has failed", ConsoleColor.Red);
|
||||
Logger.Log($"Trying to match: {pair.IsInterface}", ConsoleColor.Red);
|
||||
Logger.Log($"IsInterface: {pair.IsInterface}", ConsoleColor.Red);
|
||||
Logger.Log($"IsStruct: {pair.IsStruct}", ConsoleColor.Red);
|
||||
@ -326,6 +357,8 @@ public class ReCodeItAutoMapper
|
||||
|
||||
Logger.Log($"-------------------------------RESULT-----------------------------------", ConsoleColor.Yellow);
|
||||
Logger.Log($"Found {MappingPairs.Count()} automatic remaps", ConsoleColor.Yellow);
|
||||
Logger.Log($"Renamed {TotalFieldRenameCount} fields", ConsoleColor.Yellow);
|
||||
Logger.Log($"Renamed {TotalPropertyRenameCount} properties", ConsoleColor.Yellow);
|
||||
Logger.Log($"Failed to rename: {FailureCount} mapping pairs", ConsoleColor.Yellow);
|
||||
Logger.Log($"------------------------------------------------------------------------", ConsoleColor.Yellow);
|
||||
}
|
||||
@ -343,7 +376,7 @@ public class ReCodeItAutoMapper
|
||||
GatherMatchedTypeRefs(pair, nestedType);
|
||||
}
|
||||
|
||||
if (type == pair.OriginalTypeRef || type.Name == pair.OriginalShortName && !pair.HasBeenRenamed)
|
||||
if (type == pair.OriginalTypeDefinition)
|
||||
{
|
||||
pair.NewTypeRef = type;
|
||||
}
|
||||
@ -361,31 +394,18 @@ public class ReCodeItAutoMapper
|
||||
/// <param name="isInterface"></param>
|
||||
/// <param name="isStruct"></param>
|
||||
private sealed class MappingPair(
|
||||
TypeReference type,
|
||||
TypeDefinition type,
|
||||
string name,
|
||||
bool isInterface = false,
|
||||
bool isStruct = false,
|
||||
bool wasCollection = false)
|
||||
bool isInterface,
|
||||
bool isStruct,
|
||||
bool isPublic)
|
||||
{
|
||||
/// <summary>
|
||||
/// The type reference for the field
|
||||
/// </summary>
|
||||
public TypeReference OriginalTypeRef { get; set; } = type;
|
||||
public TypeDefinition OriginalTypeDefinition { get; private set; } = type;
|
||||
|
||||
/// <summary>
|
||||
/// The type reference we want to change
|
||||
/// </summary>
|
||||
public TypeReference NewTypeRef { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Original full name of the field type
|
||||
/// </summary>
|
||||
public string OriginalFullName { get; } = type.FullName;
|
||||
|
||||
/// <summary>
|
||||
/// Original short name of the type
|
||||
/// </summary>
|
||||
public string OriginalShortName { get; } = type.Name;
|
||||
public TypeDefinition NewTypeRef { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is this field an interface?
|
||||
@ -397,11 +417,6 @@ public class ReCodeItAutoMapper
|
||||
/// </summary>
|
||||
public bool IsStruct { get; set; } = isStruct;
|
||||
|
||||
/// <summary>
|
||||
/// Was this field a collection?
|
||||
/// </summary>
|
||||
public bool WasCollection { get; set; } = wasCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Has this type been renamed? Use for checking for failures at the end
|
||||
/// </summary>
|
||||
|
@ -156,7 +156,7 @@ public class ReCodeItRemapper
|
||||
Logger.Log("-----------------------------------------------", ConsoleColor.Green);
|
||||
Logger.Log($"Renamed {oldName} to {type.Name} directly", ConsoleColor.Green);
|
||||
|
||||
Renamer.RenameAllDirect(remap, type);
|
||||
RenameHelper.RenameAllDirect(remap, type);
|
||||
|
||||
Logger.Log("-----------------------------------------------", ConsoleColor.Green);
|
||||
}
|
||||
@ -226,7 +226,7 @@ public class ReCodeItRemapper
|
||||
highestScore.ReMap.OriginalTypeName = highestScore.Definition.Name;
|
||||
|
||||
// Rename type and all associated type members
|
||||
Renamer.RenameAll(highestScore);
|
||||
RenameHelper.RenameAll(highestScore);
|
||||
|
||||
Logger.Log("-----------------------------------------------", ConsoleColor.Green);
|
||||
}
|
||||
|
133
RecodeItLib/Remapper/RenameHelper.cs
Normal file
133
RecodeItLib/Remapper/RenameHelper.cs
Normal file
@ -0,0 +1,133 @@
|
||||
using Mono.Cecil;
|
||||
using Mono.Collections.Generic;
|
||||
using ReCodeIt.Models;
|
||||
using ReCodeIt.Utils;
|
||||
|
||||
namespace ReCodeIt.ReMapper;
|
||||
|
||||
internal static class RenameHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Only used by the manual remapper, should probably be removed
|
||||
/// </summary>
|
||||
/// <param name="score"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only used by the manual remapper, should probably be removed
|
||||
/// </summary>
|
||||
/// <param name="score"></param>
|
||||
public static void RenameAllDirect(RemapModel remap, TypeDefinition type)
|
||||
{
|
||||
var directRename = new ScoringModel();
|
||||
directRename.Definition = type;
|
||||
directRename.ReMap = remap;
|
||||
|
||||
RenameAll(directRename);
|
||||
}
|
||||
|
||||
/// <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>
|
||||
public static int RenameAllFields(
|
||||
string oldTypeName,
|
||||
string newTypeName,
|
||||
Collection<TypeDefinition> typesToCheck,
|
||||
int overAllCount = 0)
|
||||
{
|
||||
foreach (var type in typesToCheck)
|
||||
{
|
||||
int fieldCount = 0;
|
||||
foreach (var field in type.Fields)
|
||||
{
|
||||
if (field.FieldType.Name == oldTypeName)
|
||||
{
|
||||
var newFieldName = GetNewFieldName(newTypeName, field.IsPrivate, fieldCount);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/// <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,
|
||||
Collection<TypeDefinition> typesToCheck,
|
||||
int overAllCount = 0)
|
||||
{
|
||||
foreach (var type in typesToCheck)
|
||||
{
|
||||
int propertyCount = 0;
|
||||
|
||||
foreach (var property in type.Properties)
|
||||
{
|
||||
if (property.PropertyType.Name == oldTypeName)
|
||||
{
|
||||
var newName = GetNewPropertyName(newTypeName, propertyCount);
|
||||
|
||||
Logger.Log($"Renaming original property type name: `{property.PropertyType.Name}` with name `{property.Name}` to `{newName}`", ConsoleColor.Green);
|
||||
property.Name = newName;
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
using Mono.Cecil;
|
||||
using Mono.Collections.Generic;
|
||||
using ReCodeIt.Models;
|
||||
using ReCodeIt.Utils;
|
||||
|
||||
namespace ReCodeIt.ReMapper;
|
||||
|
||||
internal static class Renamer
|
||||
{
|
||||
public static void RenameAll(ScoringModel score)
|
||||
{
|
||||
var types = DataProvider.ModuleDefinition.Types;
|
||||
|
||||
// Rename all fields and properties first
|
||||
RenameAllFields(score, types);
|
||||
RenameAllProperties(score, types);
|
||||
|
||||
score.Definition.Name = score.ProposedNewName;
|
||||
}
|
||||
|
||||
public static void RenameAll()
|
||||
{
|
||||
}
|
||||
|
||||
public static void RenameAllDirect(RemapModel remap, TypeDefinition type)
|
||||
{
|
||||
var directRename = new ScoringModel();
|
||||
directRename.Definition = type;
|
||||
directRename.ReMap = remap;
|
||||
|
||||
RenameAll(directRename);
|
||||
}
|
||||
|
||||
private static void RenameAllFields(
|
||||
ScoringModel score,
|
||||
Collection<TypeDefinition> typesToCheck)
|
||||
{
|
||||
foreach (var type in typesToCheck)
|
||||
{
|
||||
int fieldCount = 0;
|
||||
foreach (var field in type.Fields)
|
||||
{
|
||||
if (field.FieldType.Name == score.Definition.Name)
|
||||
{
|
||||
var newFieldName = GetNewFieldName(score.ReMap.NewTypeName, field.IsPrivate, fieldCount);
|
||||
|
||||
if (field.Name == newFieldName) { continue; }
|
||||
|
||||
Logger.Log($"Renaming field: `{field.Name}` on OriginalTypeRef `{type.Name}` to {newFieldName}", ConsoleColor.Green);
|
||||
|
||||
field.Name = newFieldName;
|
||||
|
||||
fieldCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (type.HasNestedTypes)
|
||||
{
|
||||
foreach (var _ in type.NestedTypes)
|
||||
{
|
||||
RenameAllFields(score, type.NestedTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RenameAllProperties(
|
||||
ScoringModel score,
|
||||
Collection<TypeDefinition> typesToCheck)
|
||||
{
|
||||
foreach (var type in typesToCheck)
|
||||
{
|
||||
int propertyCount = 0;
|
||||
|
||||
foreach (var property in type.Properties)
|
||||
{
|
||||
if (property.PropertyType.Name == score.Definition.Name)
|
||||
{
|
||||
var newName = propertyCount > 0 ? $"{score.ReMap.NewTypeName}_{propertyCount}" : score.ReMap.NewTypeName;
|
||||
|
||||
Logger.Log($"Renaming Property: `{property.Name}` on OriginalTypeRef `{type}` to {newName}", ConsoleColor.Green);
|
||||
property.Name = newName;
|
||||
}
|
||||
}
|
||||
|
||||
if (type.HasNestedTypes)
|
||||
{
|
||||
foreach (var _ in type.NestedTypes)
|
||||
{
|
||||
RenameAllProperties(score, type.NestedTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetNewFieldName(string TypeName, bool isPrivate, int fieldCount = 0)
|
||||
{
|
||||
var discard = isPrivate ? "_" : "";
|
||||
string newFieldCount = fieldCount > 0 ? $"_{fieldCount}" : string.Empty;
|
||||
|
||||
return $"{discard}{char.ToLower(TypeName[0])}{TypeName[1..]}{newFieldCount}";
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user