Skip to content

Commit e7c8125

Browse files
authored
Enable trimming in .NET 6 targets (#1906)
1 parent 44a28a8 commit e7c8125

File tree

14 files changed

+242
-1
lines changed

14 files changed

+242
-1
lines changed

Rx.NET/Source/Directory.build.targets

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
1717
<DefineConstants>$(DefineConstants);HAS_WINRT;NO_NULLABLE_ATTRIBUTES</DefineConstants>
1818
</PropertyGroup>
19+
<PropertyGroup Condition="$(TargetFramework.StartsWith('net6.0')) or $(TargetFramework.StartsWith('net7.0'))">
20+
<DefineConstants>$(DefineConstants);HAS_TRIMMABILITY_ATTRIBUTES</DefineConstants>
21+
</PropertyGroup>
1922
<PropertyGroup Condition="$(TargetFramework.StartsWith('net6.0-windows')) or $(TargetFramework.StartsWith('net7.0-windows'))">
2023
<DefineConstants>$(DefineConstants);HAS_WINRT;HAS_WINFORMS;HAS_WPF;HAS_DISPATCHER;DESKTOPCLR;WINDOWS;CSWINRT</DefineConstants>
2124
</PropertyGroup>

Rx.NET/Source/src/System.Reactive/Internal/Constants.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace System.Reactive
66
{
7-
// We can't make those based on the Strings_Core.resx file, because the ObsoleteAttribute needs a compile-time constant.
7+
// We can't make those based on the Strings_Core.resx file, because attributes need a compile-time constant.
88

99
internal static class Constants_Core
1010
{
@@ -15,6 +15,9 @@ internal static class Constants_Core
1515
public const string ObsoleteSchedulerThreadpool = ObsoleteRefactoring + " Consider using Scheduler.Default to obtain the platform's most appropriate pool-based scheduler. In order to access a specific pool-based scheduler, please add a reference to the System.Reactive.PlatformServices assembly for your target platform and use the appropriate scheduler in the System.Reactive.Concurrency namespace.";
1616

1717
public const string ObsoleteSchedulerequired = "This instance property is no longer supported. Use CurrentThreadScheduler.IsScheduleRequired instead.";
18+
19+
internal const string AsQueryableTrimIncompatibilityMessage = "This type uses Queryable.AsQueryable, which is not compatible with trimming because expressions referencing IQueryable extension methods can get rebound to IEnumerable extension methods, and those IEnumerable methods might be trimmed.";
20+
internal const string EventReflectionTrimIncompatibilityMessage = "This member uses reflection to discover event members and associated delegate types.";
1821
}
1922

2023
// We can't make those based on the Strings_*.resx file, because the ObsoleteAttribute needs a compile-time constant.

Rx.NET/Source/src/System.Reactive/Internal/ReflectionUtils.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT License.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Diagnostics.CodeAnalysis;
56
using System.Globalization;
67
using System.Reflection;
78

@@ -19,6 +20,9 @@ public static Delegate CreateDelegate(Type delegateType, object o, MethodInfo me
1920
return method.CreateDelegate(delegateType, o);
2021
}
2122

23+
#if HAS_TRIMMABILITY_ATTRIBUTES
24+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
25+
#endif
2226
public static void GetEventMethods<TSender, TEventArgs>(Type targetType, object? target, string eventName, out MethodInfo addMethod, out MethodInfo removeMethod, out Type delegateType, out bool isWinRT)
2327
{
2428
EventInfo? e;

Rx.NET/Source/src/System.Reactive/Linq/IQueryLanguage.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,17 +433,53 @@ internal partial interface IQueryLanguage
433433
IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler, IScheduler scheduler);
434434
IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler);
435435
IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler);
436+
#if HAS_TRIMMABILITY_ATTRIBUTES
437+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
438+
#endif
436439
IObservable<EventPattern<object>> FromEventPattern(object target, string eventName);
440+
#if HAS_TRIMMABILITY_ATTRIBUTES
441+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
442+
#endif
437443
IObservable<EventPattern<object>> FromEventPattern(object target, string eventName, IScheduler scheduler);
444+
#if HAS_TRIMMABILITY_ATTRIBUTES
445+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
446+
#endif
438447
IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName);
448+
#if HAS_TRIMMABILITY_ATTRIBUTES
449+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
450+
#endif
439451
IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName, IScheduler scheduler);
452+
#if HAS_TRIMMABILITY_ATTRIBUTES
453+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
454+
#endif
440455
IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName);
456+
#if HAS_TRIMMABILITY_ATTRIBUTES
457+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
458+
#endif
441459
IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName, IScheduler scheduler);
460+
#if HAS_TRIMMABILITY_ATTRIBUTES
461+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
462+
#endif
442463
IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName);
464+
#if HAS_TRIMMABILITY_ATTRIBUTES
465+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
466+
#endif
443467
IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName, IScheduler scheduler);
468+
#if HAS_TRIMMABILITY_ATTRIBUTES
469+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
470+
#endif
444471
IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName);
472+
#if HAS_TRIMMABILITY_ATTRIBUTES
473+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
474+
#endif
445475
IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName, IScheduler scheduler);
476+
#if HAS_TRIMMABILITY_ATTRIBUTES
477+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
478+
#endif
446479
IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName);
480+
#if HAS_TRIMMABILITY_ATTRIBUTES
481+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
482+
#endif
447483
IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName, IScheduler scheduler);
448484

449485
IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Func<Action<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler);

Rx.NET/Source/src/System.Reactive/Linq/Observable.Events.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT License.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Diagnostics.CodeAnalysis;
56
using System.Reactive.Concurrency;
67
using System.Threading;
78

@@ -538,6 +539,9 @@ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>
538539
/// </para>
539540
/// </remarks>
540541
/// <seealso cref="ToEventPattern"/>
542+
#if HAS_TRIMMABILITY_ATTRIBUTES
543+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
544+
#endif
541545
public static IObservable<EventPattern<object>> FromEventPattern(object target, string eventName)
542546
{
543547
if (target == null)
@@ -581,6 +585,9 @@ public static IObservable<EventPattern<object>> FromEventPattern(object target,
581585
/// </para>
582586
/// </remarks>
583587
/// <seealso cref="ToEventPattern"/>
588+
#if HAS_TRIMMABILITY_ATTRIBUTES
589+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
590+
#endif
584591
public static IObservable<EventPattern<object>> FromEventPattern(object target, string eventName, IScheduler scheduler)
585592
{
586593
if (target == null)
@@ -633,6 +640,9 @@ public static IObservable<EventPattern<object>> FromEventPattern(object target,
633640
/// </para>
634641
/// </remarks>
635642
/// <seealso cref="ToEventPattern"/>
643+
#if HAS_TRIMMABILITY_ATTRIBUTES
644+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
645+
#endif
636646
public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName)
637647
{
638648
if (target == null)
@@ -677,6 +687,9 @@ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>
677687
/// </para>
678688
/// </remarks>
679689
/// <seealso cref="ToEventPattern"/>
690+
#if HAS_TRIMMABILITY_ATTRIBUTES
691+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
692+
#endif
680693
public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName, IScheduler scheduler)
681694
{
682695
if (target == null)
@@ -730,6 +743,9 @@ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>
730743
/// </para>
731744
/// </remarks>
732745
/// <seealso cref="ToEventPattern"/>
746+
#if HAS_TRIMMABILITY_ATTRIBUTES
747+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
748+
#endif
733749
public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName)
734750
{
735751
if (target == null)
@@ -775,6 +791,9 @@ public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TS
775791
/// </para>
776792
/// </remarks>
777793
/// <seealso cref="ToEventPattern"/>
794+
#if HAS_TRIMMABILITY_ATTRIBUTES
795+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
796+
#endif
778797
public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName, IScheduler scheduler)
779798
{
780799
if (target == null)
@@ -830,6 +849,9 @@ public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TS
830849
/// </para>
831850
/// </remarks>
832851
/// <seealso cref="ToEventPattern"/>
852+
#if HAS_TRIMMABILITY_ATTRIBUTES
853+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
854+
#endif
833855
public static IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName)
834856
{
835857
if (type == null)
@@ -873,6 +895,9 @@ public static IObservable<EventPattern<object>> FromEventPattern(Type type, stri
873895
/// </para>
874896
/// </remarks>
875897
/// <seealso cref="ToEventPattern"/>
898+
#if HAS_TRIMMABILITY_ATTRIBUTES
899+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
900+
#endif
876901
public static IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName, IScheduler scheduler)
877902
{
878903
if (type == null)
@@ -925,6 +950,9 @@ public static IObservable<EventPattern<object>> FromEventPattern(Type type, stri
925950
/// </para>
926951
/// </remarks>
927952
/// <seealso cref="ToEventPattern"/>
953+
#if HAS_TRIMMABILITY_ATTRIBUTES
954+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
955+
#endif
928956
public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName)
929957
{
930958
if (type == null)
@@ -969,6 +997,9 @@ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>
969997
/// </para>
970998
/// </remarks>
971999
/// <seealso cref="ToEventPattern"/>
1000+
#if HAS_TRIMMABILITY_ATTRIBUTES
1001+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
1002+
#endif
9721003
public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName, IScheduler scheduler)
9731004
{
9741005
if (type == null)
@@ -1022,6 +1053,9 @@ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>
10221053
/// </para>
10231054
/// </remarks>
10241055
/// <seealso cref="ToEventPattern"/>
1056+
#if HAS_TRIMMABILITY_ATTRIBUTES
1057+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
1058+
#endif
10251059
public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName)
10261060
{
10271061
if (type == null)
@@ -1067,6 +1101,9 @@ public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TS
10671101
/// </para>
10681102
/// </remarks>
10691103
/// <seealso cref="ToEventPattern"/>
1104+
#if HAS_TRIMMABILITY_ATTRIBUTES
1105+
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
1106+
#endif
10701107
public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName, IScheduler scheduler)
10711108
{
10721109
if (type == null)

Rx.NET/Source/src/System.Reactive/Linq/Observable.Queryable.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44

55
#pragma warning disable 1591
66

7+
using System.Diagnostics.CodeAnalysis;
8+
79
namespace System.Reactive.Linq
810
{
11+
#if HAS_TRIMMABILITY_ATTRIBUTES
12+
[RequiresUnreferencedCode(Constants_Core.AsQueryableTrimIncompatibilityMessage)]
13+
#endif
914
public static partial class Qbservable
1015
{
1116
#pragma warning disable IDE1006 // Naming Styles: 3rd party code is known to reflect for this specific field name

Rx.NET/Source/src/System.Reactive/Linq/Qbservable.Joins.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ public static QueryablePattern<TLeft, TRight> And<TLeft, TRight>(this IQbservabl
4545
#if CRIPPLED_REFLECTION
4646
InfoOf(() => And<TLeft, TRight>(default, default)),
4747
#else
48+
#pragma warning disable IL2060 // ('System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed.) This gets the MethodInfo for the method running right now, so it can't have been trimmed
4849
((MethodInfo)MethodBase.GetCurrentMethod()!).MakeGenericMethod(typeof(TLeft), typeof(TRight)),
50+
#pragma warning restore IL2060
4951
#endif
5052
left.Expression,
5153
GetSourceExpression(right)
@@ -80,7 +82,9 @@ public static QueryablePlan<TResult> Then<TSource, TResult>(this IQbservable<TSo
8082
#if CRIPPLED_REFLECTION
8183
InfoOf(() => Then<TSource, TResult>(default, default)),
8284
#else
85+
#pragma warning disable IL2060 // ('System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed.) This gets the MethodInfo for the method running right now, so it can't have been trimmed
8386
((MethodInfo)MethodBase.GetCurrentMethod()!).MakeGenericMethod(typeof(TSource), typeof(TResult)),
87+
#pragma warning restore IL2060
8488
#endif
8589
source.Expression,
8690
selector
@@ -114,7 +118,9 @@ public static IQbservable<TResult> When<TResult>(this IQbservableProvider provid
114118
#if CRIPPLED_REFLECTION
115119
InfoOf(() => When<TResult>(default, default)),
116120
#else
121+
#pragma warning disable IL2060 // ('System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed.) This gets the MethodInfo for the method running right now, so it can't have been trimmed
117122
((MethodInfo)MethodBase.GetCurrentMethod()!).MakeGenericMethod(typeof(TResult)),
123+
#pragma warning restore IL2060
118124
#endif
119125
Expression.Constant(provider, typeof(IQbservableProvider)),
120126
Expression.NewArrayInit(
@@ -151,7 +157,9 @@ public static IQbservable<TResult> When<TResult>(this IQbservableProvider provid
151157
#if CRIPPLED_REFLECTION
152158
InfoOf(() => When(default, default(IEnumerable<QueryablePlan<TResult>>))),
153159
#else
160+
#pragma warning disable IL2060 // ('System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed.) This gets the MethodInfo for the method running right now, so it can't have been trimmed
154161
((MethodInfo)MethodBase.GetCurrentMethod()!).MakeGenericMethod(typeof(TResult)),
162+
#pragma warning restore IL2060
155163
#endif
156164
Expression.Constant(provider, typeof(IQbservableProvider)),
157165
Expression.Constant(plans, typeof(IEnumerable<QueryablePlan<TResult>>))

Rx.NET/Source/src/System.Reactive/Linq/Qbservable.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ public static IQbservable<TSource> ToQbservable<TSource>(this IQueryable<TSource
5656
#if CRIPPLED_REFLECTION
5757
InfoOf(() => ToQbservable<TSource>(default)),
5858
#else
59+
#pragma warning disable IL2060 // ('System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed.) This gets the MethodInfo for the method running right now, so it can't have been trimmed
5960
((MethodInfo)MethodBase.GetCurrentMethod()!).MakeGenericMethod(typeof(TSource)),
61+
#pragma warning restore IL2060
6062
#endif
6163
source.Expression
6264
)
@@ -90,7 +92,9 @@ public static IQbservable<TSource> ToQbservable<TSource>(this IQueryable<TSource
9092
#if CRIPPLED_REFLECTION
9193
InfoOf(() => ToQbservable<TSource>(default)),
9294
#else
95+
#pragma warning disable IL2060 // ('System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed.) This gets the MethodInfo for the method running right now, so it can't have been trimmed
9396
((MethodInfo)MethodBase.GetCurrentMethod()!).MakeGenericMethod(typeof(TSource)),
97+
#pragma warning restore IL2060
9498
#endif
9599
source.Expression,
96100
Expression.Constant(scheduler)

0 commit comments

Comments
 (0)