Start refactor to new system

This commit is contained in:
Cj 2024-06-13 04:56:08 -04:00
parent 0858bae9b6
commit cefeb9638b
15 changed files with 282 additions and 58 deletions

View File

@ -1,4 +1,4 @@
using AssemblyRemapper.Reflection;
using AssemblyRemapper.Remapper;
using AssemblyRemapper.Utils;
namespace AssemblyRemapper.Commands
@ -23,7 +23,7 @@ namespace AssemblyRemapper.Commands
{
if (command == "remap" || command == "Remap")
{
var remapper = new Remapper();
var remapper = new Remapper.Remapper();
DataProvider.LoadMappingFile();
DataProvider.LoadAssemblyDefinition();

View File

@ -13,6 +13,7 @@ internal enum EFailureReason
HasGenericParameters,
HasAttribute,
IsAttribute,
Constructor,
HasMethods,
HasFields,
HasProperties,

View File

@ -2,8 +2,7 @@
internal enum EMatchResult
{
NoMatch = -1,
Disabled = 0,
SearchedNoResult = 1,
NoMatch = 1,
Match = 2,
}

View File

@ -14,9 +14,6 @@ internal class RemapModel
[JsonIgnore]
public EFailureReason FailureReason { get; set; }
[JsonIgnore]
public HashSet<ScoringModel> Scores { get; set; } = [];
public string NewTypeName { get; set; } = string.Empty;
public string OriginalTypeName { get; set; } = string.Empty;
@ -31,18 +28,39 @@ internal class RemapModel
/// </summary>
internal class SearchParams
{
#region BOOL_PARAMS
public bool? IsPublic { get; set; } = null;
public bool? IsAbstract { get; set; } = null;
public bool? IsInterface { get; set; } = null;
public bool? IsEnum { get; set; } = null;
public bool? IsNested { get; set; } = null;
public string? ParentName { get; set; } = null;
public bool? IsSealed { get; set; } = null;
public bool? HasAttribute { get; set; } = null;
public bool? IsDerived { get; set; } = null;
public bool? HasGenericParameters { get; set; } = null;
public string MatchBaseClass { get; set; }
public string IgnoreBaseClass { get; set; }
#endregion BOOL_PARAMS
#region STR_PARAMS
public string? ParentName { get; set; } = null;
public string? MatchBaseClass { get; set; } = null;
public string? IgnoreBaseClass { get; set; } = null;
#endregion STR_PARAMS
#region INT_PARAMS
public int? ConstructorParameterCount { get; set; } = null;
public int? MethodCount { get; set; } = null;
public int? FieldCount { get; set; } = null;
public int? PropertyCount { get; set; } = null;
#endregion INT_PARAMS
#region LISTS
public List<string> MatchMethods { get; set; }
public List<string> IgnoreMethods { get; set; }
public List<string> MatchFields { get; set; }
@ -52,6 +70,8 @@ internal class SearchParams
public List<string> MatchNestedTypes { get; set; }
public List<string> IgnoreNestedTypes { get; set; }
#endregion LISTS
public SearchParams()
{
}

View File

@ -1,6 +1,6 @@
using AssemblyRemapper.Utils;
namespace AssemblyRemapper.Reflection;
namespace AssemblyRemapper.Remapper;
internal static class Publicizer
{

View File

@ -1,9 +1,10 @@
using AssemblyRemapper.Enums;
using AssemblyRemapper.Models;
using AssemblyRemapper.Remapper.Search;
using AssemblyRemapper.Utils;
using Mono.Cecil;
namespace AssemblyRemapper.Reflection;
namespace AssemblyRemapper.Remapper;
internal class Remapper
{
@ -148,6 +149,12 @@ internal class Remapper
return EFailureReason.HasAttribute;
}
if (type.MatchConstructors(remap.SearchParams, score) == EMatchResult.NoMatch)
{
remap.FailureReason = EFailureReason.Constructor;
return EFailureReason.Constructor;
}
if (type.MatchMethods(remap.SearchParams, score) == EMatchResult.NoMatch)
{
remap.FailureReason = EFailureReason.HasMethods;

View File

@ -3,7 +3,7 @@ using AssemblyRemapper.Utils;
using Mono.Cecil;
using Mono.Collections.Generic;
namespace AssemblyRemapper.Reflection;
namespace AssemblyRemapper.Remapper;
internal static class Renamer
{

View File

@ -0,0 +1,36 @@
using AssemblyRemapper.Enums;
using AssemblyRemapper.Models;
using Mono.Cecil;
using Mono.Cecil.Rocks;
namespace AssemblyRemapper.Remapper.Search;
internal static class Constructors
{
/// <summary>
/// Search for types with a constructor of a given length
/// </summary>
/// <param name="parms"></param>
/// <param name="score"></param>
/// <returns>Match if constructor parameters matches</returns>
public static EMatchResult GetTypeByParameterCount(TypeDefinition type, SearchParams parms, ScoringModel score)
{
if (parms.ConstructorParameterCount is null)
{
return EMatchResult.Disabled;
}
var constructors = type.GetConstructors();
foreach (var constructor in constructors)
{
if (constructor.Parameters.Count == parms.ConstructorParameterCount)
{
score.Score++;
return EMatchResult.Match;
}
}
return EMatchResult.NoMatch;
}
}

View File

@ -0,0 +1,5 @@
namespace AssemblyRemapper.Remapper.Search;
internal static class Fields
{
}

View File

@ -0,0 +1,99 @@
using AssemblyRemapper.Enums;
using AssemblyRemapper.Models;
using Mono.Cecil;
using Mono.Cecil.Rocks;
namespace AssemblyRemapper.Remapper.Search;
internal static class Methods
{
/// <summary>
/// returns a match on all types with the specified methods
/// </summary>
/// <param name="type"></param>
/// <param name="parms"></param>
/// <param name="score"></param>
/// <returns>Match if type contains any supplied methods</returns>
public static EMatchResult GetTypeWithMethods(TypeDefinition type, SearchParams parms, ScoringModel score)
{
var matchCount = 0;
// Handle match methods
foreach (var method in type.Methods)
{
foreach (var name in parms.MatchMethods)
{
// Method name match
if (method.Name == name)
{
matchCount += 1;
score.Score++;
}
}
}
return matchCount > 0
? EMatchResult.Match
: EMatchResult.NoMatch;
}
/// <summary>
/// Returns a match on all types without methods
/// </summary>
/// <param name="type"></param>
/// <param name="parms"></param>
/// <param name="score"></param>
/// <returns>Match if type has no methods</returns>
public static EMatchResult GetTypeWithoutMethods(TypeDefinition type, SearchParams parms, ScoringModel score)
{
if (parms.IgnoreMethods is null) return EMatchResult.Disabled;
var skippAll = parms.IgnoreMethods.Contains("*");
var methodCount = type.Methods.Count - type.GetConstructors().Count();
// Subtract method count from constructor count to check for real methods
if (methodCount is 0 && skippAll is true)
{
score.Score++;
return EMatchResult.Match;
}
return EMatchResult.NoMatch;
}
/// <summary>
/// Get all types without the specified method
/// </summary>
/// <param name="type"></param>
/// <param name="parms"></param>
/// <param name="score"></param>
/// <returns></returns>
public static EMatchResult GetTypeWithNoMethods(TypeDefinition type, SearchParams parms, ScoringModel score)
{
if (parms.IgnoreMethods is null) { return EMatchResult.Disabled; }
foreach (var method in type.Methods)
{
if (parms.IgnoreMethods.Contains(method.Name))
{
return EMatchResult.NoMatch;
}
}
score.Score++;
return EMatchResult.Match;
}
public static EMatchResult GetTypeByNumberOfMethods(TypeDefinition type, SearchParams parms, ScoringModel score)
{
if (parms.MethodCount is null) { return EMatchResult.Disabled; }
if (type.Methods.Count == parms.MethodCount)
{
score.Score++;
return EMatchResult.Match;
}
return EMatchResult.NoMatch;
}
}

View File

@ -0,0 +1,5 @@
namespace AssemblyRemapper.Remapper.Search;
internal class NestedTypes
{
}

View File

@ -0,0 +1,6 @@
namespace AssemblyRemapper.Remapper.Search
{
internal class Properties
{
}
}

View File

@ -1,11 +1,12 @@
using AssemblyRemapper.Enums;
using AssemblyRemapper.Models;
using AssemblyRemapper.Utils;
using Mono.Cecil;
using Mono.Cecil.Rocks;
namespace AssemblyRemapper.Reflection;
namespace AssemblyRemapper.Remapper.Search;
internal static class SearchExtentions
internal static class TypeDefExtensions
{
public static EMatchResult MatchIsAbstract(this TypeDefinition type, SearchParams parms, ScoringModel score)
{
@ -181,52 +182,56 @@ internal static class SearchExtentions
return EMatchResult.NoMatch;
}
public static EMatchResult MatchConstructors(this TypeDefinition type, SearchParams parms, ScoringModel score)
{
var matches = new List<EMatchResult> { };
if (parms.ConstructorParameterCount is not null)
{
matches.Add(Constructors.GetTypeByParameterCount(type, parms, score));
}
return matches.GetMatch();
}
/// <summary>
/// Handle running all method matching routines
/// </summary>
/// <returns>Match if any search criteria met</returns>
public static EMatchResult MatchMethods(this TypeDefinition type, SearchParams parms, ScoringModel score)
{
// We're not searching for methods and this type contains methods
if (parms.MatchMethods.Count is 0 && parms.IgnoreMethods.Count is 0)
{
return EMatchResult.Disabled;
}
var matches = new List<EMatchResult> { };
var skippAll = parms.IgnoreMethods.Contains("*");
var methodCount = type.Methods.Count - type.GetConstructors().Count();
// Subtract method count from constructor count to check for real methods
if (methodCount is 0 && skippAll is true)
if (parms.MatchMethods.Count > 0 && parms.IgnoreMethods.Contains("*") is true)
{
return EMatchResult.Match;
}
// Handle Ignore methods
foreach (var method in type.Methods)
{
if (parms.IgnoreMethods.Contains(method.Name))
{
// Contains blacklisted method, no match
score.FailureReason = EFailureReason.HasMethods;
score.Score--;
Logger.Log($"Cannot both ignore all methods and search for a method on {score.ProposedNewName}.", ConsoleColor.Red);
return EMatchResult.NoMatch;
}
else if (parms.MatchMethods.Count > 0)
{
matches.Add(Methods.GetTypeWithMethods(type, parms, score));
}
var matchCount = 0;
// Handle match methods
foreach (var method in type.Methods)
if (parms.IgnoreMethods.Count > 0)
{
foreach (var name in parms.MatchMethods)
{
// Method name match
if (method.Name == name)
{
matchCount += 1;
score.Score++;
}
}
Logger.Log("TypeWithoutMethods");
matches.Add(Methods.GetTypeWithoutMethods(type, parms, score));
}
return matchCount > 0 ? EMatchResult.Match : EMatchResult.NoMatch;
if (parms.IgnoreMethods.Contains("*"))
{
Logger.Log("TypeWithNoMethods");
matches.Add(Methods.GetTypeWithNoMethods(type, parms, score));
}
if (parms.MethodCount > 0)
{
Logger.Log("TypeByNumberOfMethods");
matches.Add(Methods.GetTypeByNumberOfMethods(type, parms, score));
}
// return match if any condition matched
return matches.GetMatch();
}
public static EMatchResult MatchFields(this TypeDefinition type, SearchParams parms, ScoringModel score)
@ -241,6 +246,7 @@ internal static class SearchExtentions
// Type has fields, we dont want any
if (type.HasFields is false && skippAll is true)
{
score.Score++;
return EMatchResult.Match;
}

View File

@ -0,0 +1,23 @@
using AssemblyRemapper.Enums;
namespace AssemblyRemapper.Utils;
internal static class EnumExtensions
{
/// <summary>
/// Returns a match from a list of match results
/// </summary>
/// <param name="matches"></param>
/// <returns>highest EMatchResult</returns>
public static EMatchResult GetMatch(this List<EMatchResult> matches)
{
if (matches.Contains(EMatchResult.Disabled)) { return EMatchResult.Disabled; }
if (matches.Contains(EMatchResult.NoMatch)) { return EMatchResult.NoMatch; }
if (matches.Contains(EMatchResult.Match)) { return EMatchResult.Match; }
// default to disabled
return EMatchResult.Disabled;
}
}

View File

@ -1,23 +1,40 @@
[
// TEMPLATE
// NOTE: You only need to add the properties you need inside of `SearchParams`
// NOTE: Only add the properties you need inside of `SearchParams`
// The remapper will take any and all consideration you give it
// it uses any input you give it its matching, so only use parameters you need.
// Tldr; The remapper is a giant state machine, you get what you ask for
{
"NewTypeName": "TEMPLATE", // This is the name we want to change it to
"OriginalTypeName": "", // This is the name of the object in the assembly, Can be used to store what type you're changing as its not read unless "UseDirectRename" is true, it is also written to after remapping
"UseForceRename": false, // If this is true, directly remap using the name in the assembly from the above property
"SearchParams": { // null means disabled
"IsPublic": null, // Is the Type public? (bool)
"IsAbstract": null, // Is the Type Abstract? (bool)
"IsInterface": null, // Is the Type an Interface? (bool)
"IsEnum": null, // Is the Type an Enum? (bool)
"IsNested": null, // Is the Type Nested? (bool)
"ParentName": "", // The Name of the parent type if it is nested, can be left empty (string)
"IsSealed": null, // Is the Type Sealed? (bool)
"HasAttribute": null, // Does the Type have an attribute? (bool)
"IsDerived": null, // Does the Type inherit from another Type? (bool)
// Bool parameters
"IsPublic": false, // Is the Type public?
"IsAbstract": false, // Is the Type Abstract?
"IsInterface": false, // Is the Type an Interface?
"IsEnum": false, // Is the Type an Enum?
"IsNested": false, // Is the Type Nested?
"IsSealed": false, // Is the Type Sealed?
"HasAttribute": false, // Does the Type have an attribute?
"IsDerived": false, // Does the Type inherit from another Type?
"HasGenericParameters": false, // Does the type have generic parameters?
// String parameters
"ParentName": "", // The Name of the parent type (IsNested must be enabled)
"MatchBaseClass": "", // Base class to match (IsDerived must be enabled)
"IgnoreBaseClass": "", // Base class to ignore (IsDerived must be enabled)
"HasGenericParameters": null, // Does the type have generic parameters? (bool)
// Integer parameters
"ConstructorParameterCount": 0, // Match types that have a constructor parameter of this length
"MethodCount": 0, // Match types that have a method count this length
"FieldCount": 0, // Match types that have a method count this length
"PropertyCount": 0, // Match types that have a method count this length
// Note:
// - You can can filter the ignore list with a wild card '*' to match all types that have none of that search parameter
// - These are all lists of strings