326 lines
11 KiB
C#
326 lines
11 KiB
C#
|
using AssemblyRemapper.Models;
|
|||
|
using AssemblyRemapper.Utils;
|
|||
|
using Mono.Cecil;
|
|||
|
using Mono.Cecil.Rocks;
|
|||
|
|
|||
|
namespace AssemblyRemapper.Reflection;
|
|||
|
|
|||
|
internal static class SearchProvider
|
|||
|
{
|
|||
|
public static int MatchCount { get; private set; }
|
|||
|
|
|||
|
public static EMatchResult MatchIsAbstract(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
if (parms.IsAbstract is null)
|
|||
|
{
|
|||
|
return EMatchResult.Disabled;
|
|||
|
}
|
|||
|
|
|||
|
// Interfaces cannot be abstract, and abstract cannot be static
|
|||
|
if (type.IsInterface || type.GetStaticConstructor() != null)
|
|||
|
{
|
|||
|
Logger.Log($"Searching for an abstract type, skipping interface or static");
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
if (type.IsAbstract != parms.IsAbstract)
|
|||
|
{
|
|||
|
score.Score += 1;
|
|||
|
Logger.Log($"Matched `{type.Name}` on search `{score.ProposedNewName}` : IsAbstract");
|
|||
|
return EMatchResult.Match;
|
|||
|
}
|
|||
|
|
|||
|
Logger.Log($"Skipping `{type.Name}` on search `{score.ProposedNewName}` IsAbstract does not match.");
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchIsEnum(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
if (parms.IsEnum is null)
|
|||
|
{
|
|||
|
return EMatchResult.Disabled;
|
|||
|
}
|
|||
|
|
|||
|
if (type.IsEnum == parms.IsEnum)
|
|||
|
{
|
|||
|
score.Score += 1;
|
|||
|
Logger.Log($"Matched `{type.Name}` on search `{score.ProposedNewName}` : IsEnum");
|
|||
|
return EMatchResult.Match;
|
|||
|
}
|
|||
|
|
|||
|
Logger.Log($"Skipping `{type.Name}` on search `{score.ProposedNewName}` IsEnum does not match.");
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchIsNested(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
if (parms.IsNested is null)
|
|||
|
{
|
|||
|
return EMatchResult.Disabled;
|
|||
|
}
|
|||
|
|
|||
|
if (type.IsNested == parms.IsNested)
|
|||
|
{
|
|||
|
score.Score += 1;
|
|||
|
Logger.Log($"Matched `{type.Name}` on search `{score.ProposedNewName}` : IsNested");
|
|||
|
return EMatchResult.Match;
|
|||
|
}
|
|||
|
|
|||
|
Logger.Log($"Skipping `{type.Name}` on search `{score.ProposedNewName}` IsNested does not match.");
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchIsSealed(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
if (parms.IsSealed is null)
|
|||
|
{
|
|||
|
return EMatchResult.Disabled;
|
|||
|
}
|
|||
|
|
|||
|
if (type.IsSealed == parms.IsSealed)
|
|||
|
{
|
|||
|
score.Score += 1;
|
|||
|
Logger.Log($"Matched `{type.Name}` on search `{score.ProposedNewName}` : IsSealed");
|
|||
|
return EMatchResult.Match;
|
|||
|
}
|
|||
|
|
|||
|
Logger.Log($"Skipping `{type.Name}` on search `{score.ProposedNewName}` IsSealed does not match.");
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchIsDerived(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
if (parms.IsDerived is null)
|
|||
|
{
|
|||
|
return EMatchResult.Disabled;
|
|||
|
}
|
|||
|
|
|||
|
if (type.BaseType != null && (bool)parms.IsDerived)
|
|||
|
{
|
|||
|
score.Score += 1;
|
|||
|
Logger.Log($"Matched `{type.Name}` on search `{score.ProposedNewName}` : IsDerived");
|
|||
|
return EMatchResult.Match;
|
|||
|
}
|
|||
|
|
|||
|
Logger.Log($"Skipping `{type.Name}` on search `{score.ProposedNewName}` IsDerived does not match.");
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchIsInterface(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
if (parms.IsInterface is null)
|
|||
|
{
|
|||
|
return EMatchResult.Disabled;
|
|||
|
}
|
|||
|
|
|||
|
// Interfaces cannot be a class
|
|||
|
if (type.IsClass)
|
|||
|
{
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
if (type.IsInterface != parms.IsInterface)
|
|||
|
{
|
|||
|
score.Score += 1;
|
|||
|
Logger.Log($"Matched `{type.Name}` on search `{score.ProposedNewName}` : IsInterface");
|
|||
|
return EMatchResult.Match;
|
|||
|
}
|
|||
|
|
|||
|
Logger.Log($"Skipping `{type.Name}` on search `{score.ProposedNewName}` IsInterface does not match.");
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchIsGeneric(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
if (parms.IsGeneric is null)
|
|||
|
{
|
|||
|
return EMatchResult.Disabled;
|
|||
|
}
|
|||
|
|
|||
|
if (type.HasGenericParameters == parms.IsGeneric)
|
|||
|
{
|
|||
|
score.Score += 1;
|
|||
|
Logger.Log($"Matched `{type.Name}` on search `{score.ProposedNewName}` : IsGeneric");
|
|||
|
return EMatchResult.Match;
|
|||
|
}
|
|||
|
|
|||
|
Logger.Log($"Skipping `{type.Name}` on search `{score.ProposedNewName}` IsGeneric does not match.");
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchIsPublic(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
if (parms.IsPublic is null)
|
|||
|
{
|
|||
|
return EMatchResult.Disabled;
|
|||
|
}
|
|||
|
|
|||
|
if (type.IsPublic == parms.IsPublic)
|
|||
|
{
|
|||
|
score.Score += 1;
|
|||
|
Logger.Log($"Matched `{type.Name}` on search `{score.ProposedNewName}` : IsPublic");
|
|||
|
return EMatchResult.Match;
|
|||
|
}
|
|||
|
|
|||
|
Logger.Log($"Skipping `{type.Name}` on search `{score.ProposedNewName}` IsPublic does not match.");
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchHasAttribute(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
if (parms.HasAttribute is null)
|
|||
|
{
|
|||
|
return EMatchResult.Disabled;
|
|||
|
}
|
|||
|
|
|||
|
if (type.HasCustomAttributes == parms.HasAttribute)
|
|||
|
{
|
|||
|
score.Score += 1;
|
|||
|
Logger.Log($"Matched `{type.Name}` on search `{score.ProposedNewName}` : HasAttribute");
|
|||
|
return EMatchResult.Match;
|
|||
|
}
|
|||
|
|
|||
|
Logger.Log($"Skipping `{type.Name}` on search `{score.ProposedNewName}` HasAttribute does not match.");
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchMethods(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
// Ignore types that dont have methods when we are looking for them, and ignore types that
|
|||
|
// have methods while we're not looking for them
|
|||
|
if ((type.HasMethods is true && parms.MethodNamesToMatch.Count == 0) || (type.HasMethods is false && parms.MethodNamesToMatch.Count > 0))
|
|||
|
{
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
// `*` is the wildcard to ignore all methods that exist on types
|
|||
|
if (parms.MethodNamesToIgnore.Contains("*"))
|
|||
|
{
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
int matchCount = 0;
|
|||
|
|
|||
|
foreach (var method in type.Methods)
|
|||
|
{
|
|||
|
if (parms.MethodNamesToIgnore.Contains(method.Name))
|
|||
|
{
|
|||
|
// Type contains blacklisted method
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
if (parms.MethodNamesToMatch.Contains(method.Name))
|
|||
|
{
|
|||
|
matchCount++;
|
|||
|
score.Score += 2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return matchCount > 0 ? EMatchResult.Match : EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchFields(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
// Ignore types that dont have fields when we are looking for them, and ignore types that
|
|||
|
// have fields while we're not looking for them
|
|||
|
if ((type.HasFields is true && parms.FieldNamesToMatch.Count == 0) || (type.HasFields is false && parms.FieldNamesToMatch.Count > 0))
|
|||
|
{
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
// `*` is the wildcard to ignore all fields that exist on types
|
|||
|
if (parms.FieldNamesToIgnore.Contains("*"))
|
|||
|
{
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
int matchCount = 0;
|
|||
|
|
|||
|
foreach (var field in type.Fields)
|
|||
|
{
|
|||
|
if (parms.FieldNamesToIgnore.Contains(field.Name))
|
|||
|
{
|
|||
|
// Type contains blacklisted field
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
if (parms.FieldNamesToMatch.Contains(field.Name))
|
|||
|
{
|
|||
|
matchCount++;
|
|||
|
score.Score += 2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return matchCount > 0 ? EMatchResult.Match : EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchProperties(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
// Ignore types that dont have properties when we are looking for them, and ignore types
|
|||
|
// that have properties while we're not looking for them
|
|||
|
if ((type.HasProperties is true && parms.PropertyNamesToMatch.Count == 0) || (type.HasProperties is false && parms.PropertyNamesToMatch.Count > 0))
|
|||
|
{
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
// `*` is the wildcard to ignore all properties that exist on types
|
|||
|
if (parms.PropertyNamesToIgnore.Contains("*"))
|
|||
|
{
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
int matchCount = 0;
|
|||
|
|
|||
|
foreach (var property in type.Properties)
|
|||
|
{
|
|||
|
if (parms.PropertyNamesToIgnore.Contains(property.Name))
|
|||
|
{
|
|||
|
// Type contains blacklisted property
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
if (parms.PropertyNamesToMatch.Contains(property.Name))
|
|||
|
{
|
|||
|
matchCount++;
|
|||
|
score.Score += 2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return matchCount > 0 ? EMatchResult.Match : EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
public static EMatchResult MatchNestedTypes(this TypeDefinition type, RemapSearchParams parms, ScoringModel score)
|
|||
|
{
|
|||
|
// Ignore types that dont have nested types when we are looking for them, and ignore types
|
|||
|
// that have nested types while we're not looking for them
|
|||
|
if ((type.HasNestedTypes is true && parms.NestedTypesToMatch.Count == 0) || (type.HasNestedTypes is false && parms.NestedTypesToMatch.Count > 0))
|
|||
|
{
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
// `*` is the wildcard to ignore all nested types that exist on types
|
|||
|
if (parms.PropertyNamesToIgnore.Contains("*"))
|
|||
|
{
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
int matchCount = 0;
|
|||
|
|
|||
|
foreach (var nestedType in type.NestedTypes)
|
|||
|
{
|
|||
|
if (parms.NestedTypesToIgnore.Contains(nestedType.Name))
|
|||
|
{
|
|||
|
// Type contains blacklisted nested type
|
|||
|
return EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
|
|||
|
if (parms.NestedTypesToMatch.Contains(nestedType.Name))
|
|||
|
{
|
|||
|
matchCount++;
|
|||
|
score.Score += 2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return matchCount > 0 ? EMatchResult.Match : EMatchResult.NoMatch;
|
|||
|
}
|
|||
|
}
|