DTLib.Demystifier/src/Ben.Demystifier/Internal/ReflectionHelper.cs
Bruno Garcia 243029cc29
Allow use as git submodule
* build in sentry csproj

* typo

* public GetFrames
2021-01-11 03:44:04 +00:00

63 lines
2.5 KiB
C#

// Copyright (c) Ben A Adams. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
namespace System.Diagnostics.Internal
{
/// <summary>
/// A helper class that contains utilities methods for dealing with reflection.
/// </summary>
public static class ReflectionHelper
{
private static PropertyInfo? tranformerNamesLazyPropertyInfo;
/// <summary>
/// Returns true if the <paramref name="type"/> is a value tuple type.
/// </summary>
public static bool IsValueTuple(this Type type)
{
return type.Namespace == "System" && type.Name.Contains("ValueTuple`");
}
/// <summary>
/// Returns true if the given <paramref name="attribute"/> is of type <code>TupleElementNameAttribute</code>.
/// </summary>
/// <remarks>
/// To avoid compile-time depencency hell with System.ValueTuple, this method uses reflection and not checks statically that
/// the given <paramref name="attribute"/> is <code>TupleElementNameAttribute</code>.
/// </remarks>
public static bool IsTupleElementNameAttribue(this Attribute attribute)
{
var attributeType = attribute.GetType();
return attributeType.Namespace == "System.Runtime.CompilerServices" &&
attributeType.Name == "TupleElementNamesAttribute";
}
/// <summary>
/// Returns 'TransformNames' property value from a given <paramref name="attribute"/>.
/// </summary>
/// <remarks>
/// To avoid compile-time depencency hell with System.ValueTuple, this method uses reflection
/// instead of casting the attribute to a specific type.
/// </remarks>
public static IList<string>? GetTransformerNames(this Attribute attribute)
{
Debug.Assert(attribute.IsTupleElementNameAttribue());
var propertyInfo = GetTransformNamesPropertyInfo(attribute.GetType());
return propertyInfo?.GetValue(attribute) as IList<string>;
}
private static PropertyInfo? GetTransformNamesPropertyInfo(Type attributeType)
{
#pragma warning disable 8634
return LazyInitializer.EnsureInitialized(ref tranformerNamesLazyPropertyInfo,
#pragma warning restore 8634
() => attributeType.GetProperty("TransformNames", BindingFlags.Instance | BindingFlags.Public));
}
}
}