Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make a bit of BenchmarkDotNet trimmable #2046

Merged
merged 2 commits into from
Jul 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace System.Diagnostics.CodeAnalysis
/// </remarks>
[AttributeUsage(
AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter |
AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method,
AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Class,
Inherited = false)]
internal sealed class DynamicallyAccessedMembersAttribute : Attribute
{
Expand Down
4 changes: 4 additions & 0 deletions src/BenchmarkDotNet/BenchmarkDotNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
<ItemGroup>
<ProjectReference Include="..\BenchmarkDotNet.Annotations\BenchmarkDotNet.Annotations.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<Compile Include="..\BenchmarkDotNet.Annotations\Attributes\DynamicallyAccessedMembersAttribute.cs" Link="Properties\DynamicallyAccessedMembersAttribute.cs" />
<Compile Include="..\BenchmarkDotNet.Annotations\Attributes\DynamicallyAccessedMemberTypes.cs" Link="Properties\DynamicallyAccessedMemberTypes.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\BenchmarkDotNet.Disassembler.x64\DataContracts.cs" Link="Disassemblers\DataContracts.cs" />
</ItemGroup>
Expand Down
14 changes: 8 additions & 6 deletions src/BenchmarkDotNet/Characteristics/Characteristic.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using static BenchmarkDotNet.Characteristics.CharacteristicHelper;

namespace BenchmarkDotNet.Characteristics
Expand All @@ -7,39 +8,39 @@ public abstract class Characteristic
{
public static readonly object EmptyValue = new object();

public static Characteristic<T> Create<TOwner, T>(string memberName)
public static Characteristic<T> Create<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName)
where TOwner : CharacteristicObject
=> new Characteristic<T>(
memberName,
typeof(TOwner),
null, default,
false);

public static Characteristic<T> Create<TOwner, T>(string memberName, T fallbackValue)
public static Characteristic<T> Create<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName, T fallbackValue)
where TOwner : CharacteristicObject
=> new Characteristic<T>(
memberName,
typeof(TOwner),
null, fallbackValue,
false);

public static Characteristic<T> Create<TOwner, T>(string memberName, Func<CharacteristicObject, T, T> resolver, T fallbackValue, bool ignoreOnApply)
public static Characteristic<T> Create<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName, Func<CharacteristicObject, T, T> resolver, T fallbackValue, bool ignoreOnApply)
where TOwner : CharacteristicObject
=> new Characteristic<T>(
memberName,
typeof(TOwner),
resolver, fallbackValue,
ignoreOnApply);

public static Characteristic<T> CreateHidden<TOwner, T>(string memberName)
public static Characteristic<T> CreateHidden<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName)
where TOwner : CharacteristicObject
=> new Characteristic<T>(
memberName,
typeof(TOwner),
null, default,
false, true);

public static Characteristic<T> CreateIgnoreOnApply<TOwner, T>(string memberName)
public static Characteristic<T> CreateIgnoreOnApply<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName)
where TOwner : CharacteristicObject
=> new Characteristic<T>(
memberName,
Expand All @@ -49,7 +50,7 @@ public static Characteristic<T> CreateIgnoreOnApply<TOwner, T>(string memberName

protected Characteristic(
string id,
Type characteristicType,
[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicType,
Type declaringType,
object fallbackValue,
bool ignoreOnApply,
Expand Down Expand Up @@ -78,6 +79,7 @@ protected Characteristic(

public bool DontShowInSummary { get; }

[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)]
public Type CharacteristicType { get; }

public Type DeclaringType { get; }
Expand Down
20 changes: 14 additions & 6 deletions src/BenchmarkDotNet/Characteristics/CharacteristicHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
Expand Down Expand Up @@ -39,14 +40,16 @@ public static bool IsPresentableCharacteristic(this Characteristic c, bool inclu
[PublicAPI] public static IReadOnlyList<Characteristic> GetThisTypeCharacteristics(this CharacteristicObject obj) =>
GetThisTypeCharacteristics(obj.GetType());

public static IReadOnlyList<Characteristic> GetThisTypeCharacteristics(Type characteristicObjectType)
public static IReadOnlyList<Characteristic> GetThisTypeCharacteristics(
[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType)
{
if (!IsCharacteristicObjectSubclass(characteristicObjectType))
return EmptyCharacteristics;
return ThisTypeCharacteristics.GetOrAdd(characteristicObjectType, GetThisTypeCharacteristicsCore);
}

private static IReadOnlyList<Characteristic> GetThisTypeCharacteristicsCore(Type characteristicObjectType)
private static IReadOnlyList<Characteristic> GetThisTypeCharacteristicsCore(
[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType)
{
var fieldValues = characteristicObjectType.GetTypeInfo()
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static)
Expand All @@ -73,14 +76,16 @@ private static IReadOnlyList<Characteristic> GetThisTypeCharacteristicsCore(Type
public static IReadOnlyList<Characteristic> GetAllCharacteristics(this CharacteristicObject obj) =>
GetAllCharacteristics(obj.GetType());

public static IReadOnlyList<Characteristic> GetAllCharacteristics(Type characteristicObjectType)
public static IReadOnlyList<Characteristic> GetAllCharacteristics(
[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType)
{
if (!IsCharacteristicObjectSubclass(characteristicObjectType))
return EmptyCharacteristics;
return AllTypeCharacteristics.GetOrAdd(characteristicObjectType, GetAllCharacteristicsCore);
}

private static IReadOnlyList<Characteristic> GetAllCharacteristicsCore(Type characteristicObjectType)
private static IReadOnlyList<Characteristic> GetAllCharacteristicsCore(
[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType)
{
var result = new List<Characteristic>();

Expand All @@ -90,7 +95,8 @@ private static IReadOnlyList<Characteristic> GetAllCharacteristicsCore(Type char
}

private static void FillAllCharacteristicsCore(
Type characteristicObjectType, List<Characteristic> result, HashSet<Characteristic> visited)
[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType,
List<Characteristic> result, HashSet<Characteristic> visited)
{
// DONTTOUCH: DO NOT change the order of characteristic as it may break logic of some operations.

Expand All @@ -113,7 +119,9 @@ private static void FillAllCharacteristicsCore(
}
}

public static IReadOnlyList<Characteristic> GetAllPresentableCharacteristics(Type characteristicObjectType, bool includeIgnoreOnApply = false) =>
public static IReadOnlyList<Characteristic> GetAllPresentableCharacteristics(
[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType,
bool includeIgnoreOnApply = false) =>
GetAllCharacteristics(characteristicObjectType)
.Where(c => c.IsPresentableCharacteristic(includeIgnoreOnApply))
.ToArray();
Expand Down
20 changes: 14 additions & 6 deletions src/BenchmarkDotNet/Characteristics/CharacteristicObject.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;

using NotNullAttribute = JetBrains.Annotations.NotNullAttribute;

namespace BenchmarkDotNet.Characteristics
{
// TODO: better naming.
[DynamicallyAccessedMembers(CharacteristicMemberTypes)]
public abstract class CharacteristicObject
{
#region IdCharacteristic

internal const DynamicallyAccessedMemberTypes CharacteristicMemberTypes =
DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties
| DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields;

protected static string ResolveId(CharacteristicObject obj, string actual)
{
if (!string.IsNullOrEmpty(actual) && actual != IdCharacteristic.FallbackValue)
Expand Down Expand Up @@ -134,7 +142,7 @@ public bool HasValue(Characteristic characteristic)
return false;
}

internal T GetValue<T>(Characteristic<T> characteristic)
internal T GetValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic)
{
return (T)GetValue((Characteristic)characteristic);
}
Expand All @@ -154,12 +162,12 @@ private object ResolveCore(Characteristic characteristic, object result)
#endregion

#region Resolve
public T ResolveValue<T>(Characteristic<T> characteristic, IResolver resolver)
public T ResolveValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, IResolver resolver)
{
return resolver.Resolve(this, characteristic);
}

public T ResolveValue<T>(Characteristic<T> characteristic, IResolver resolver, T defaultValue)
public T ResolveValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, IResolver resolver, T defaultValue)
{
return resolver.Resolve(this, characteristic, defaultValue);
}
Expand All @@ -174,7 +182,7 @@ public object ResolveValue(Characteristic characteristic, IResolver resolver, ob
return resolver.Resolve(this, characteristic, defaultValue);
}

public T ResolveValue<T>(Characteristic<T> characteristic, T defaultValue)
public T ResolveValue<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, T defaultValue)
{
return HasValue(characteristic) ? GetValue(characteristic) : (T)characteristic.ResolveValueCore(this, defaultValue);
}
Expand All @@ -185,14 +193,14 @@ public object ResolveValue(Characteristic characteristic, object defaultValue)
return HasValue(characteristic) ? GetValue(characteristic) : characteristic.ResolveValueCore(this, defaultValue);
}

public T? ResolveValueAsNullable<T>(Characteristic<T> characteristic) where T : struct
public T? ResolveValueAsNullable<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic) where T : struct
{
return HasValue(characteristic) ? GetValue(characteristic) : (T?)null;
}
#endregion

#region Set value
internal void SetValue<T>(Characteristic<T> characteristic, T value)
internal void SetValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, T value)
{
SetValue((Characteristic)characteristic, value);
}
Expand Down
9 changes: 5 additions & 4 deletions src/BenchmarkDotNet/Characteristics/CharacteristicObject`1.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using JetBrains.Annotations;
using System.Diagnostics.CodeAnalysis;
using JetBrains.Annotations;

namespace BenchmarkDotNet.Characteristics
{
Expand Down Expand Up @@ -32,10 +33,10 @@ public T Apply(params CharacteristicObject[] others)

public new T UnfreezeCopy() => (T)UnfreezeCopyCore();

protected static Characteristic<TC> CreateCharacteristic<TC>(string memberName) => Characteristic.Create<T, TC>(memberName);
protected static Characteristic<TC> CreateCharacteristic<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] TC>(string memberName) => Characteristic.Create<T, TC>(memberName);

protected static Characteristic<TC> CreateHiddenCharacteristic<TC>(string memberName) => Characteristic.CreateHidden<T, TC>(memberName);
protected static Characteristic<TC> CreateHiddenCharacteristic<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] TC>(string memberName) => Characteristic.CreateHidden<T, TC>(memberName);

protected static Characteristic<TC> CreateIgnoreOnApplyCharacteristic<TC>(string memberName) => Characteristic.CreateIgnoreOnApply<T, TC>(memberName);
protected static Characteristic<TC> CreateIgnoreOnApplyCharacteristic<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] TC>(string memberName) => Characteristic.CreateIgnoreOnApply<T, TC>(memberName);
}
}
3 changes: 2 additions & 1 deletion src/BenchmarkDotNet/Characteristics/Characteristic`1.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System;
using System.Diagnostics.CodeAnalysis;

namespace BenchmarkDotNet.Characteristics
{
public class Characteristic<T> : Characteristic
public class Characteristic<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T> : Characteristic
{
internal Characteristic(
string id,
Expand Down
5 changes: 3 additions & 2 deletions src/BenchmarkDotNet/Characteristics/CompositeResolver.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

namespace BenchmarkDotNet.Characteristics
Expand All @@ -25,7 +26,7 @@ public object Resolve(CharacteristicObject obj, Characteristic characteristic)
throw new InvalidOperationException($"There is no default resolver for {characteristic.FullId}");
}

public T Resolve<T>(CharacteristicObject obj, Characteristic<T> characteristic)
public T Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic)
{
if (obj.HasValue(characteristic))
return characteristic[obj];
Expand All @@ -47,7 +48,7 @@ public object Resolve(CharacteristicObject obj, Characteristic characteristic, o
return defaultValue;
}

public T Resolve<T>(CharacteristicObject obj, Characteristic<T> characteristic, T defaultValue)
public T Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic, T defaultValue)
{
if (obj.HasValue(characteristic))
return characteristic[obj];
Expand Down
8 changes: 5 additions & 3 deletions src/BenchmarkDotNet/Characteristics/IResolver.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace BenchmarkDotNet.Characteristics
using System.Diagnostics.CodeAnalysis;

namespace BenchmarkDotNet.Characteristics
{
/// <summary>
/// An entity which can resolve default values of <see cref="Characteristic{T}"/>.
Expand All @@ -9,10 +11,10 @@ public interface IResolver

object Resolve(CharacteristicObject obj, Characteristic characteristic);

T Resolve<T>(CharacteristicObject obj, Characteristic<T> characteristic);
T Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic);

object Resolve(CharacteristicObject obj, Characteristic characteristic, object defaultValue);

T Resolve<T>(CharacteristicObject obj, Characteristic<T> characteristic, T defaultValue);
T Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic, T defaultValue);
}
}
9 changes: 5 additions & 4 deletions src/BenchmarkDotNet/Characteristics/Resolver.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace BenchmarkDotNet.Characteristics
{
public class Resolver : IResolver
{
private readonly Dictionary<Characteristic, Func<CharacteristicObject, object>> resolvers = new Dictionary<Characteristic, Func<CharacteristicObject, object>>();

protected void Register<T>(Characteristic<T> characteristic, Func<T> resolver) =>
protected void Register<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, Func<T> resolver) =>
resolvers[characteristic] = obj => resolver();

protected void Register<T>(Characteristic<T> characteristic, Func<CharacteristicObject, T> resolver) =>
protected void Register<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, Func<CharacteristicObject, T> resolver) =>
resolvers[characteristic] = obj => resolver(obj);

public bool CanResolve(Characteristic characteristic) => resolvers.ContainsKey(characteristic);
Expand All @@ -25,7 +26,7 @@ public object Resolve(CharacteristicObject obj, Characteristic characteristic)
throw new InvalidOperationException($"There is no default resolver for {characteristic.FullId}");
}

public T Resolve<T>(CharacteristicObject obj, Characteristic<T> characteristic)
public T Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic)
{
if (obj.HasValue(characteristic))
return characteristic[obj];
Expand All @@ -46,7 +47,7 @@ public object Resolve(CharacteristicObject obj, Characteristic characteristic, o
return defaultValue;
}

public T Resolve<T>(CharacteristicObject obj, Characteristic<T> characteristic, T defaultValue)
public T Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic, T defaultValue)
{
if (obj.HasValue(characteristic))
return characteristic[obj];
Expand Down
3 changes: 0 additions & 3 deletions src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,6 @@ private string GenerateProjectForNuGetBuild(BuildPartition buildPartition, Artif
<ItemGroup>
<Compile Include=""{Path.GetFileName(artifactsPaths.ProgramCodePath)}"" Exclude=""bin\**;obj\**;**\*.xproj;packages\**"" />
</ItemGroup>
<ItemGroup>
<TrimmerRootAssembly Include=""BenchmarkDotNet"" />
</ItemGroup>
<ItemGroup>
<PackageReference Include=""Microsoft.DotNet.ILCompiler"" Version=""{ilCompilerVersion}"" />
<ProjectReference Include=""{GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger).FullName}"" />
Expand Down