From d7d76e0d8a1ffb73fc8fc969f497f396b8861d01 Mon Sep 17 00:00:00 2001 From: Cj <161484149+CJ-SPT@users.noreply.github.com> Date: Thu, 13 Jun 2024 01:46:51 -0400 Subject: [PATCH] Update --- AssemblyRemapper/Models/RemapModel.cs | 16 ++++- AssemblyRemapper/Models/ScoringModel.cs | 66 +------------------ AssemblyRemapper/Reflection/Remapper.cs | 52 ++++++++++++--- AssemblyRemapper/Reflection/Renamer.cs | 6 +- .../Reflection/SearchExtentions.cs | 29 +++++--- AssemblyRemapper/Utils/ExtentionMethods.cs | 63 ++++++++++++++++++ Templates/MappingTemplate.jsonc | 5 +- 7 files changed, 147 insertions(+), 90 deletions(-) create mode 100644 AssemblyRemapper/Utils/ExtentionMethods.cs diff --git a/AssemblyRemapper/Models/RemapModel.cs b/AssemblyRemapper/Models/RemapModel.cs index 286fb0d..0e32a7c 100644 --- a/AssemblyRemapper/Models/RemapModel.cs +++ b/AssemblyRemapper/Models/RemapModel.cs @@ -1,10 +1,22 @@ -namespace AssemblyRemapper.Models; +using AssemblyRemapper.Enums; +using Newtonsoft.Json; + +namespace AssemblyRemapper.Models; /// /// Object to store linq statements in inside of json to search and remap classes /// internal class RemapModel { + [JsonIgnore] + public bool Succeeded { get; set; } = false; + + [JsonIgnore] + public EFailureReason FailureReason { get; set; } + + [JsonIgnore] + public HashSet Scores { get; set; } = []; + public string NewTypeName { get; set; } = string.Empty; public string OriginalTypeName { get; set; } = string.Empty; @@ -29,6 +41,8 @@ internal class SearchParams 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; } public List MatchMethods { get; set; } public List IgnoreMethods { get; set; } public List MatchFields { get; set; } diff --git a/AssemblyRemapper/Models/ScoringModel.cs b/AssemblyRemapper/Models/ScoringModel.cs index f35785f..91d064d 100644 --- a/AssemblyRemapper/Models/ScoringModel.cs +++ b/AssemblyRemapper/Models/ScoringModel.cs @@ -1,5 +1,4 @@ using AssemblyRemapper.Enums; -using AssemblyRemapper.Utils; using Mono.Cecil; namespace AssemblyRemapper.Models; @@ -9,74 +8,11 @@ internal class ScoringModel public string ProposedNewName { get; set; } public int Score { get; set; } = 0; public TypeDefinition Definition { get; set; } - public RemapModel RemapModel { get; internal set; } + public RemapModel ReMap { get; internal set; } public EFailureReason FailureReason { get; set; } = EFailureReason.None; public ScoringModel() { } -} - -internal static class ScoringModelExtensions -{ - public static void AddScoreToResult(this ScoringModel model) - { - try - { - if (DataProvider.ScoringModels.TryGetValue(model.ProposedNewName, out HashSet modelHashset)) - { - foreach (var outVal in modelHashset) - { - if (outVal.Definition.Name == model.Definition.Name) - { - Logger.Log("Skipping adding duplicate type match to list", ConsoleColor.Yellow); - return; - } - } - - modelHashset.Add(model); - return; - } - - var newHash = new HashSet - { - model - }; - - DataProvider.ScoringModels.Add(model.ProposedNewName, newHash); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - } - } - - public static int CalculateMaxScore(this ScoringModel score) - { - // Score should never be null here, but if it is we're fucked so just return 0. - if (score == null) { return 0; } - - var propInfos = typeof(SearchParams).GetProperties(); - - int maxScore = 0; - - foreach (var propInfo in propInfos) - { - object value = propInfo.GetValue(score.RemapModel.SearchParams); - - if (value == null) continue; - - if (value is List list) - { - maxScore += list.Count; - } - else - { - maxScore++; - } - } - - return maxScore; - } } \ No newline at end of file diff --git a/AssemblyRemapper/Reflection/Remapper.cs b/AssemblyRemapper/Reflection/Remapper.cs index fccb52c..3ac2377 100644 --- a/AssemblyRemapper/Reflection/Remapper.cs +++ b/AssemblyRemapper/Reflection/Remapper.cs @@ -70,79 +70,94 @@ internal class Remapper var score = new ScoringModel { ProposedNewName = remap.NewTypeName, - RemapModel = remap, + ReMap = remap, Definition = type, }; // Set the original type name to be used later - score.RemapModel.OriginalTypeName = type.Name; + score.ReMap.OriginalTypeName = type.Name; if (type.MatchIsAbstract(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.IsAbstract; return EFailureReason.IsAbstract; } if (type.MatchIsEnum(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.IsEnum; return EFailureReason.IsEnum; } if (type.MatchIsNested(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.IsNested; return EFailureReason.IsNested; } if (type.MatchIsSealed(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.IsSealed; return EFailureReason.IsSealed; } if (type.MatchIsDerived(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.IsDerived; return EFailureReason.IsDerived; } if (type.MatchIsInterface(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.IsInterface; return EFailureReason.IsInterface; } if (type.MatchHasGenericParameters(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.HasGenericParameters; return EFailureReason.HasGenericParameters; } if (type.MatchIsPublic(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.IsPublic; return EFailureReason.IsPublic; } if (type.MatchHasAttribute(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.HasAttribute; return EFailureReason.HasAttribute; } if (type.MatchMethods(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.HasMethods; return EFailureReason.HasMethods; } if (type.MatchFields(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.HasFields; return EFailureReason.HasFields; } if (type.MatchProperties(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.HasProperties; return EFailureReason.HasProperties; } if (type.MatchNestedTypes(remap.SearchParams, score) == EMatchResult.NoMatch) { + remap.FailureReason = EFailureReason.HasNestedTypes; return EFailureReason.HasNestedTypes; } remap.OriginalTypeName = type.Name; + remap.Succeeded = true; + remap.FailureReason = EFailureReason.None; score.AddScoreToResult(); return EFailureReason.None; @@ -154,6 +169,8 @@ internal class Remapper var oldName = type.Name; remap.OriginalTypeName = type.Name; + remap.FailureReason = EFailureReason.None; + remap.Succeeded = true; type.Name = remap.NewTypeName; Logger.Log("-----------------------------------------------", ConsoleColor.Green); @@ -170,17 +187,34 @@ internal class Remapper { ChooseBestMatch(score.Value, true); } + + var failures = 0; + var changes = 0; + + foreach (var remap in DataProvider.Remaps) + { + if (remap.Succeeded is false) + { + Logger.Log("-----------------------------------------------", ConsoleColor.Red); + Logger.Log($"Renaming {remap.NewTypeName} failed with reason {remap.FailureReason}", ConsoleColor.Red); + Logger.Log("-----------------------------------------------", ConsoleColor.Red); + failures++; + return; + } + + changes++; + } + + Logger.Log("-----------------------------------------------", ConsoleColor.Yellow); + Logger.Log($"Result: Remapped {changes} Types. Failed to remap {failures} Types", ConsoleColor.Yellow); + Logger.Log("-----------------------------------------------", ConsoleColor.Yellow); } private void ChooseBestMatch(HashSet scores, bool isBest = false) { - if (scores.Count == 0) - { - return; - } + if (scores.Count == 0) { return; } var highestScore = scores.OrderByDescending(score => score.Score).FirstOrDefault(); - var nextHighestScores = scores.OrderByDescending(score => score.Score).Skip(1); if (highestScore is null) { return; } @@ -190,7 +224,7 @@ internal class Remapper Logger.Log("-----------------------------------------------", ConsoleColor.Green); Logger.Log($"Renaming {highestScore.Definition.Name} to {highestScore.ProposedNewName}", ConsoleColor.Green); - Logger.Log($"Max possible score: {highestScore.CalculateMaxScore()}", ConsoleColor.Green); + Logger.Log($"Max possible score: {highestScore.ReMap.SearchParams.CalculateMaxScore()}", ConsoleColor.Green); Logger.Log($"Scored: {highestScore.Score} points", ConsoleColor.Green); if (scores.Count > 1) @@ -203,7 +237,7 @@ internal class Remapper } } - highestScore.RemapModel.OriginalTypeName = highestScore.Definition.Name; + highestScore.ReMap.OriginalTypeName = highestScore.Definition.Name; // Rename type and all associated type members Renamer.RenameAll(highestScore); diff --git a/AssemblyRemapper/Reflection/Renamer.cs b/AssemblyRemapper/Reflection/Renamer.cs index 6e063fb..a6e5dbd 100644 --- a/AssemblyRemapper/Reflection/Renamer.cs +++ b/AssemblyRemapper/Reflection/Renamer.cs @@ -22,7 +22,7 @@ internal static class Renamer { var directRename = new ScoringModel(); directRename.Definition = type; - directRename.RemapModel = remap; + directRename.ReMap = remap; RenameAll(directRename); } @@ -38,7 +38,7 @@ internal static class Renamer { if (field.FieldType.Name == score.Definition.Name) { - var newFieldName = GetNewFieldName(score.RemapModel.NewTypeName, field.IsPrivate, fieldCount); + var newFieldName = GetNewFieldName(score.ReMap.NewTypeName, field.IsPrivate, fieldCount); if (field.Name == newFieldName) { continue; } @@ -72,7 +72,7 @@ internal static class Renamer { if (property.PropertyType.Name == score.Definition.Name) { - var newName = propertyCount > 0 ? $"{score.RemapModel.NewTypeName}_{propertyCount}" : score.RemapModel.NewTypeName; + var newName = propertyCount > 0 ? $"{score.ReMap.NewTypeName}_{propertyCount}" : score.ReMap.NewTypeName; Logger.Log($"Renaming Property: `{property.Name}` on Type `{type}` to {newName}", ConsoleColor.Green); property.Name = newName; diff --git a/AssemblyRemapper/Reflection/SearchExtentions.cs b/AssemblyRemapper/Reflection/SearchExtentions.cs index 34feaf0..5c09407 100644 --- a/AssemblyRemapper/Reflection/SearchExtentions.cs +++ b/AssemblyRemapper/Reflection/SearchExtentions.cs @@ -88,12 +88,22 @@ internal static class SearchExtentions return EMatchResult.Disabled; } - if (type.BaseType != null && (bool)parms.IsDerived) + if (type.BaseType is not null && (bool)parms.IsDerived is true) { score.Score++; return EMatchResult.Match; } + if (type.BaseType?.Name == parms.MatchBaseClass) + { + return EMatchResult.Match; + } + + if (type.BaseType?.Name == parms.IgnoreBaseClass) + { + return EMatchResult.NoMatch; + } + score.FailureReason = EFailureReason.IsDerived; return EMatchResult.NoMatch; } @@ -183,10 +193,9 @@ internal static class SearchExtentions var methodCount = type.Methods.Count - type.GetConstructors().Count(); // Subtract method count from constructor count to check for real methods - if (methodCount > 0 && skippAll is true) + if (methodCount is 0 && skippAll is true) { - // Type has methods, we dont want any - return EMatchResult.NoMatch; + return EMatchResult.Match; } // Handle Ignore methods @@ -230,9 +239,9 @@ internal static class SearchExtentions var skippAll = parms.IgnoreFields.Contains("*"); // Type has fields, we dont want any - if (type.HasFields is true && skippAll is true) + if (type.HasFields is false && skippAll is true) { - return EMatchResult.NoMatch; + return EMatchResult.Match; } int matchCount = 0; @@ -269,9 +278,9 @@ internal static class SearchExtentions var skippAll = parms.IgnorePropterties.Contains("*"); // Type has fields, we dont want any - if (type.HasProperties is true && skippAll is true) + if (type.HasProperties is false && skippAll is true) { - return EMatchResult.NoMatch; + return EMatchResult.Match; } foreach (var property in type.Properties) @@ -308,10 +317,10 @@ internal static class SearchExtentions var skippAll = parms.IgnorePropterties.Contains("*"); // `*` is the wildcard to ignore all fields that exist on types - if (type.HasNestedTypes is true && skippAll is true) + if (type.HasNestedTypes is false && skippAll is true) { score.FailureReason = EFailureReason.HasNestedTypes; - return EMatchResult.NoMatch; + return EMatchResult.Match; } foreach (var nestedType in type.NestedTypes) diff --git a/AssemblyRemapper/Utils/ExtentionMethods.cs b/AssemblyRemapper/Utils/ExtentionMethods.cs new file mode 100644 index 0000000..ca32e06 --- /dev/null +++ b/AssemblyRemapper/Utils/ExtentionMethods.cs @@ -0,0 +1,63 @@ +using AssemblyRemapper.Models; + +namespace AssemblyRemapper.Utils; + +internal static class ExtentionMethods +{ + public static void AddScoreToResult(this ScoringModel model) + { + try + { + if (DataProvider.ScoringModels.TryGetValue(model.ProposedNewName, out HashSet modelHashset)) + { + foreach (var outVal in modelHashset) + { + if (outVal.Definition.Name == model.Definition.Name) + { + Logger.Log("Skipping adding duplicate type match to list", ConsoleColor.Yellow); + return; + } + } + + modelHashset.Add(model); + return; + } + + var newHash = new HashSet + { + model + }; + + DataProvider.ScoringModels.Add(model.ProposedNewName, newHash); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + public static int CalculateMaxScore(this SearchParams parms) + { + var propInfos = typeof(SearchParams).GetProperties(); + + int maxScore = 0; + + foreach (var propInfo in propInfos) + { + object value = propInfo.GetValue(parms); + + if (value == null) continue; + + if (value is List list) + { + maxScore += list.Count; + } + else + { + maxScore++; + } + } + + return maxScore; + } +} \ No newline at end of file diff --git a/Templates/MappingTemplate.jsonc b/Templates/MappingTemplate.jsonc index 47c23d3..11b6126 100644 --- a/Templates/MappingTemplate.jsonc +++ b/Templates/MappingTemplate.jsonc @@ -15,12 +15,13 @@ "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) + "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) - // 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 - + "MatchMethods": [ // This is a list of methods we want to match ], "IgnoreMethods": [ // This is a list of methods we want to ignore