Skip to content

Commit

Permalink
adds InnerTypes() and extensions for AccessTool methods on type Type
Browse files Browse the repository at this point in the history
  • Loading branch information
pardeike committed Dec 27, 2023
1 parent 8444af2 commit d916a30
Show file tree
Hide file tree
Showing 2 changed files with 388 additions and 4 deletions.
29 changes: 25 additions & 4 deletions Harmony/Tools/AccessTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@

namespace HarmonyLib
{
// ---------------------------------------------------------------------------------------------------------------------
// NOTE:
// When adding or updating methods that have a first argument of 'Type type, please create/update a corresponding method
// and xml documentation in AccessToolsExtensions!
// ---------------------------------------------------------------------------------------------------------------------

/// <summary>A helper class for reflection related functions</summary>
///
public static class AccessTools
{
/// <summary>Shortcut for <see cref="BindingFlags"/> to simplify the use of reflections and make it work for any access level</summary>
///
// Note: This should a be const, but changing from static (readonly) to const breaks binary compatibility.
public static readonly BindingFlags all = BindingFlags.Public
public static readonly BindingFlags all = BindingFlags.Public // This should a be const, but changing from static (readonly) to const breaks binary compatibility.
| BindingFlags.NonPublic
| BindingFlags.Instance
| BindingFlags.Static
Expand All @@ -34,11 +39,11 @@ public static class AccessTools

/// <summary>Shortcut for <see cref="BindingFlags"/> to simplify the use of reflections and make it work for any access level but only within the current type</summary>
///
// Note: This should a be const, but changing from static (readonly) to const breaks binary compatibility.
public static readonly BindingFlags allDeclared = all | BindingFlags.DeclaredOnly;
public static readonly BindingFlags allDeclared = all | BindingFlags.DeclaredOnly; // This should a be const, but changing from static (readonly) to const breaks binary compatibility.

/// <summary>Enumerates all assemblies in the current app domain, excluding visual studio assemblies</summary>
/// <returns>An enumeration of <see cref="Assembly"/></returns>
///
public static IEnumerable<Assembly> AllAssemblies()
{
return AppDomain.CurrentDomain.GetAssemblies().Where(a => a.FullName.StartsWith("Microsoft.VisualStudio") is false);
Expand Down Expand Up @@ -81,11 +86,21 @@ public static Type[] GetTypesFromAssembly(Assembly assembly)

/// <summary>Enumerates all successfully loaded types in the current app domain, excluding visual studio assemblies</summary>
/// <returns>An enumeration of all <see cref="Type"/> in all assemblies, excluding visual studio assemblies</returns>
///
public static IEnumerable<Type> AllTypes()
{
return AllAssemblies().SelectMany(a => GetTypesFromAssembly(a));
}

/// <summary>Enumerates all inner types (non-recursive) of a given type</summary>
/// <param name="type">The class/type to start with</param>
/// <returns>An enumeration of all inner <see cref="Type"/></returns>
///
public static IEnumerable<Type> InnerTypes(Type type)
{
return type.GetNestedTypes(all);
}

/// <summary>Applies a function going up the type hierarchy and stops at the first non-<c>null</c> result</summary>
/// <typeparam name="T">Result type of func()</typeparam>
/// <param name="type">The class/type to start with</param>
Expand Down Expand Up @@ -423,6 +438,7 @@ public static MethodInfo PropertyGetter(string typeColonName)
/// <param name="type">The class/type</param>
/// <param name="parameters">Optional parameters to target a specific overload of multiple indexers</param>
/// <returns>A method or null when type is null or when the indexer property cannot be found</returns>
///
public static MethodInfo IndexerGetter(Type type, Type[] parameters = null)
{
return Indexer(type, parameters)?.GetGetMethod(true);
Expand Down Expand Up @@ -451,6 +467,7 @@ public static MethodInfo PropertySetter(string typeColonName)
/// <param name="type">The class/type</param>
/// <param name="parameters">Optional parameters to target a specific overload of multiple indexers</param>
/// <returns>A method or null when type is null or when the indexer property cannot be found</returns>
///
public static MethodInfo IndexerSetter(Type type, Type[] parameters = null)
{
return Indexer(type, parameters)?.GetSetMethod(true);
Expand Down Expand Up @@ -571,6 +588,7 @@ public static MethodInfo Method(string typeColonName, Type[] parameters = null,
/// <summary>Gets the <see cref="IEnumerator.MoveNext"/> method of an enumerator method</summary>
/// <param name="method">Enumerator method that creates the enumerator <see cref="IEnumerator" /></param>
/// <returns>The internal <see cref="IEnumerator.MoveNext"/> method of the enumerator or <b>null</b> if no valid enumerator is detected</returns>
///
public static MethodInfo EnumeratorMoveNext(MethodBase method)
{
if (method is null)
Expand Down Expand Up @@ -604,6 +622,7 @@ public static MethodInfo EnumeratorMoveNext(MethodBase method)
/// <summary>Gets the <see cref="IAsyncStateMachine.MoveNext"/> method of an async method's state machine</summary>
/// <param name="method">Async method that creates the state machine internally</param>
/// <returns>The internal <see cref="IAsyncStateMachine.MoveNext"/> method of the async state machine or <b>null</b> if no valid async method is detected</returns>
///
public static MethodInfo AsyncMoveNext(MethodBase method)
{
if (method is null)
Expand Down Expand Up @@ -1176,6 +1195,7 @@ public static FieldRef<object, F> FieldRefAccess<F>(Type type, string fieldName)
/// <typeparam name="F"> type of the field</typeparam>
/// <param name="typeColonName">The member in the form <c>TypeFullName:MemberName</c>, where TypeFullName matches the form recognized by <a href="https://docs.microsoft.com/en-us/dotnet/api/system.type.gettype">Type.GetType</a> like <c>Some.Namespace.Type</c>.</param>
/// <returns>A readable/assignable <see cref="FieldRef{T,F}"/> delegate with <c>T=object</c></returns>
///
public static FieldRef<object, F> FieldRefAccess<F>(string typeColonName)
{
var info = Tools.TypColonName(typeColonName);
Expand Down Expand Up @@ -1864,6 +1884,7 @@ public static T CreateInstance<T>()
/// <summary>
/// A cache for the <see cref="ICollection{T}.Add"/> or similar Add methods for different types.
/// </summary>
///
static readonly Dictionary<Type, FastInvokeHandler> addHandlerCache = new();

#if NET35
Expand Down
Loading

0 comments on commit d916a30

Please sign in to comment.