mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-15 00:12:50 +08:00
Adding polysharp properly
This commit is contained in:
parent
c7c3ebdf57
commit
e1d21e7e61
@ -9,6 +9,7 @@
|
|||||||
<PackageVersion Include="IsExternalInit" Version="1.0.3" />
|
<PackageVersion Include="IsExternalInit" Version="1.0.3" />
|
||||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
|
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
|
||||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
||||||
|
<PackageVersion Include="PolySharp" Version="1.14.1" />
|
||||||
<PackageVersion Include="Shouldly" Version="4.2.1" />
|
<PackageVersion Include="Shouldly" Version="4.2.1" />
|
||||||
<PackageVersion Include="Spectre.Verify.Extensions" Version="22.3.2-preview.0.1" />
|
<PackageVersion Include="Spectre.Verify.Extensions" Version="22.3.2-preview.0.1" />
|
||||||
<PackageVersion Include="Verify.Xunit" Version="28.2.1" />
|
<PackageVersion Include="Verify.Xunit" Version="28.2.1" />
|
||||||
|
@ -2,6 +2,11 @@ namespace Spectre.Console;
|
|||||||
|
|
||||||
internal static class TypeConverterHelper
|
internal static class TypeConverterHelper
|
||||||
{
|
{
|
||||||
|
internal const DynamicallyAccessedMemberTypes ConverterAnnotation = DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields;
|
||||||
|
|
||||||
|
internal static bool IsGetConverterSupported =>
|
||||||
|
!AppContext.TryGetSwitch("Spectre.Console.TypeConverterHelper.IsGetConverterSupported ", out var enabled) || enabled;
|
||||||
|
|
||||||
public static string ConvertToString<T>(T input)
|
public static string ConvertToString<T>(T input)
|
||||||
{
|
{
|
||||||
var result = GetTypeConverter<T>().ConvertToInvariantString(input);
|
var result = GetTypeConverter<T>().ConvertToInvariantString(input);
|
||||||
@ -51,7 +56,7 @@ internal static class TypeConverterHelper
|
|||||||
|
|
||||||
public static TypeConverter GetTypeConverter<T>()
|
public static TypeConverter GetTypeConverter<T>()
|
||||||
{
|
{
|
||||||
var converter = TypeDescriptor.GetConverter(typeof(T));
|
var converter = GetConverter();
|
||||||
if (converter != null)
|
if (converter != null)
|
||||||
{
|
{
|
||||||
return converter;
|
return converter;
|
||||||
@ -72,5 +77,91 @@ internal static class TypeConverterHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw new InvalidOperationException("Could not find type converter");
|
throw new InvalidOperationException("Could not find type converter");
|
||||||
|
|
||||||
|
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2087", Justification = "Feature switches are not currently supported in the analyzer")]
|
||||||
|
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026", Justification = "Feature switches are not currently supported in the analyzer")]
|
||||||
|
static TypeConverter? GetConverter()
|
||||||
|
{
|
||||||
|
if (!IsGetConverterSupported)
|
||||||
|
{
|
||||||
|
return GetIntrinsicConverter(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TypeDescriptor.GetConverter(typeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate TypeConverter FuncWithDam([DynamicallyAccessedMembers(ConverterAnnotation)] Type type);
|
||||||
|
|
||||||
|
private static readonly Dictionary<Type, FuncWithDam> _intrinsicConverters;
|
||||||
|
|
||||||
|
static TypeConverterHelper()
|
||||||
|
{
|
||||||
|
_intrinsicConverters = new()
|
||||||
|
{
|
||||||
|
[typeof(bool)] = _ => new BooleanConverter(),
|
||||||
|
[typeof(byte)] = _ => new ByteConverter(),
|
||||||
|
[typeof(sbyte)] = _ => new SByteConverter(),
|
||||||
|
[typeof(char)] = _ => new CharConverter(),
|
||||||
|
[typeof(double)] = _ => new DoubleConverter(),
|
||||||
|
[typeof(string)] = _ => new StringConverter(),
|
||||||
|
[typeof(int)] = _ => new Int32Converter(),
|
||||||
|
[typeof(short)] = _ => new Int16Converter(),
|
||||||
|
[typeof(long)] = _ => new Int64Converter(),
|
||||||
|
[typeof(float)] = _ => new SingleConverter(),
|
||||||
|
[typeof(ushort)] = _ => new UInt16Converter(),
|
||||||
|
[typeof(uint)] = _ => new UInt32Converter(),
|
||||||
|
[typeof(ulong)] = _ => new UInt64Converter(),
|
||||||
|
[typeof(object)] = _ => new TypeConverter(),
|
||||||
|
[typeof(CultureInfo)] = _ => new CultureInfoConverter(),
|
||||||
|
[typeof(DateTime)] = _ => new DateTimeConverter(),
|
||||||
|
[typeof(DateTimeOffset)] = _ => new DateTimeOffsetConverter(),
|
||||||
|
[typeof(decimal)] = _ => new DecimalConverter(),
|
||||||
|
[typeof(TimeSpan)] = _ => new TimeSpanConverter(),
|
||||||
|
[typeof(Guid)] = _ => new GuidConverter(),
|
||||||
|
[typeof(Uri)] = _ => new UriTypeConverter(),
|
||||||
|
[typeof(Array)] = _ => new ArrayConverter(),
|
||||||
|
[typeof(ICollection)] = _ => new CollectionConverter(),
|
||||||
|
[typeof(Enum)] = CreateEnumConverter(),
|
||||||
|
#if !NETSTANDARD2_0
|
||||||
|
[typeof(Int128)] = _ => new Int128Converter(),
|
||||||
|
[typeof(Half)] = _ => new HalfConverter(),
|
||||||
|
[typeof(UInt128)] = _ => new UInt128Converter(),
|
||||||
|
[typeof(DateOnly)] = _ => new DateOnlyConverter(),
|
||||||
|
[typeof(TimeOnly)] = _ => new TimeOnlyConverter(),
|
||||||
|
[typeof(Version)] = _ => new VersionConverter(),
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2111", Justification = "Delegate reflection is safe for all usages in this type.")]
|
||||||
|
private static FuncWithDam CreateEnumConverter() => ([DynamicallyAccessedMembers(ConverterAnnotation)] Type type) => new EnumConverter(type);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A highly-constrained version of <see cref="TypeDescriptor.GetConverter(Type)" /> that only returns intrinsic converters.
|
||||||
|
/// </summary>
|
||||||
|
private static TypeConverter? GetIntrinsicConverter([DynamicallyAccessedMembers(ConverterAnnotation)] Type type)
|
||||||
|
{
|
||||||
|
if (type.IsArray)
|
||||||
|
{
|
||||||
|
type = typeof(Array);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof(ICollection).IsAssignableFrom(type))
|
||||||
|
{
|
||||||
|
type = typeof(ICollection);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.IsEnum)
|
||||||
|
{
|
||||||
|
type = typeof(Enum);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_intrinsicConverters.TryGetValue(type, out var factory))
|
||||||
|
{
|
||||||
|
return factory(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,7 +23,7 @@
|
|||||||
<PackageReference Include="Wcwidth.Sources">
|
<PackageReference Include="Wcwidth.Sources">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="PolySharp" Version="1.14.1">
|
<PackageReference Include="PolySharp">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
namespace Spectre.Console;
|
namespace Spectre.Console;
|
||||||
|
|
||||||
#pragma warning disable IL2026,IL2070,IL2075,IL3050
|
// ExceptionFormatter relies heavily on reflection of types unknown until runtime.
|
||||||
|
// We'll suppress these warnings, but alert the user this method is not supported.
|
||||||
|
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode")]
|
||||||
|
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2070:RequiresUnreferencedCode")]
|
||||||
|
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2075:RequiresUnreferencedCode")]
|
||||||
|
[RequiresDynamicCode(AotWarning)]
|
||||||
internal static class ExceptionFormatter
|
internal static class ExceptionFormatter
|
||||||
{
|
{
|
||||||
public const string AotWarning = "ExceptionFormatter is currently not supported for AOT.";
|
public const string AotWarning = "ExceptionFormatter is currently not supported for AOT.";
|
||||||
|
|
||||||
[RequiresDynamicCode(ExceptionFormatter.AotWarning)]
|
|
||||||
public static IRenderable Format(Exception exception, ExceptionSettings settings)
|
public static IRenderable Format(Exception exception, ExceptionSettings settings)
|
||||||
{
|
{
|
||||||
if (exception is null)
|
if (exception is null)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user