Skip to content

Commit e9a9108

Browse files
authored
Add trimming annotations to DotNetObjectReference (#41610)
1 parent 55f1e2f commit e9a9108

9 files changed

+43
-37
lines changed

src/Components/Web/src/Microsoft.AspNetCore.Components.Web.WarningSuppressions.xml

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<linker>
3-
<assembly fullname="Microsoft.AspNetCore.Components.Web, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
4-
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
5-
<argument>ILLink</argument>
6-
<argument>IL2026</argument>
7-
<property name="Scope">member</property>
8-
<property name="Target">M:Microsoft.AspNetCore.Components.Web.Infrastructure.JSComponentInterop.SetRootComponentParameters(System.Int32,System.Int32,System.Text.Json.JsonElement,System.Text.Json.JsonSerializerOptions)</property>
9-
</attribute>
10-
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
11-
<argument>ILLink</argument>
12-
<argument>IL2026</argument>
13-
<property name="Scope">member</property>
14-
<property name="Target">M:Microsoft.AspNetCore.Components.Web.WebEventData.ParseEventArgsJson(Microsoft.AspNetCore.Components.RenderTree.Renderer,System.Text.Json.JsonSerializerOptions,System.UInt64,System.String,System.Text.Json.JsonElement)</property>
15-
</attribute>
3+
<assembly fullname="Microsoft.AspNetCore.Components.Web, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
164
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
175
<argument>ILLink</argument>
186
<argument>IL2062</argument>
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<linker>
33
<assembly fullname="Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60">
44
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
@@ -7,11 +7,5 @@
77
<property name="Scope">member</property>
88
<property name="Target">F:Microsoft.Extensions.DependencyInjection.WebAssemblyAuthenticationServiceCollectionExtensions.&lt;&gt;c__1`1.&lt;&gt;9__1_0</property>
99
</attribute>
10-
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
11-
<argument>ILLink</argument>
12-
<argument>IL2091</argument>
13-
<property name="Scope">member</property>
14-
<property name="Target">M:Microsoft.Extensions.DependencyInjection.WebAssemblyAuthenticationServiceCollectionExtensions.&lt;&gt;c__1`1.&lt;AddAuthenticationStateProvider&gt;b__1_0(System.IServiceProvider)</property>
15-
</attribute>
1610
</assembly>
17-
</linker>
11+
</linker>

src/JSInterop/Microsoft.JSInterop/src/DotNetObjectReference.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Diagnostics.CodeAnalysis;
5+
using static Microsoft.AspNetCore.Internal.LinkerFlags;
6+
47
namespace Microsoft.JSInterop;
58

69
/// <summary>
@@ -13,7 +16,7 @@ public static class DotNetObjectReference
1316
/// </summary>
1417
/// <param name="value">The reference type to track.</param>
1518
/// <returns>An instance of <see cref="DotNetObjectReference{TValue}" />.</returns>
16-
public static DotNetObjectReference<TValue> Create<TValue>(TValue value) where TValue : class
19+
public static DotNetObjectReference<TValue> Create<[DynamicallyAccessedMembers(JSInvokable)] TValue>(TValue value) where TValue : class
1720
{
1821
if (value is null)
1922
{

src/JSInterop/Microsoft.JSInterop/src/DotNetObjectReferenceOfT.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Diagnostics;
5+
using System.Diagnostics.CodeAnalysis;
56
using Microsoft.JSInterop.Infrastructure;
7+
using static Microsoft.AspNetCore.Internal.LinkerFlags;
68

79
namespace Microsoft.JSInterop;
810

@@ -13,7 +15,8 @@ namespace Microsoft.JSInterop;
1315
/// To avoid leaking memory, the reference must later be disposed by JS code or by .NET code.
1416
/// </summary>
1517
/// <typeparam name="TValue">The type of the value to wrap.</typeparam>
16-
public sealed class DotNetObjectReference<TValue> : IDotNetObjectReference, IDisposable where TValue : class
18+
public sealed class DotNetObjectReference<[DynamicallyAccessedMembers(JSInvokable)] TValue> :
19+
IDotNetObjectReference, IDisposable where TValue : class
1720
{
1821
private readonly TValue _value;
1922
private long _objectId;

src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetDispatcher.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@
1111
using System.Text;
1212
using System.Text.Json;
1313
using Microsoft.AspNetCore.Internal;
14+
using static Microsoft.AspNetCore.Internal.LinkerFlags;
1415

15-
[assembly: MetadataUpdateHandler(typeof(Microsoft.JSInterop.Infrastructure.DotNetDispatcher))]
16+
[assembly: MetadataUpdateHandler(typeof(Microsoft.JSInterop.Infrastructure.DotNetDispatcher.MetadataUpdateHandler))]
1617

1718
namespace Microsoft.JSInterop.Infrastructure;
1819

1920
/// <summary>
2021
/// Provides methods that receive incoming calls from JS to .NET.
2122
/// </summary>
22-
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070", Justification = "Linker does not propogate annotations to generated state machine. https://github.com/mono/linker/issues/1403")]
2323
public static class DotNetDispatcher
2424
{
2525
private const string DisposeDotNetObjectReferenceMethodName = "__Dispose";
@@ -394,7 +394,7 @@ private static (MethodInfo methodInfo, Type[] parameterTypes) GetCachedMethodInf
394394
throw new ArgumentException($"The type '{type.Name}' does not contain a public invokable method with [{nameof(JSInvokableAttribute)}(\"{methodIdentifier}\")].");
395395
}
396396

397-
static Dictionary<string, (MethodInfo, Type[])> ScanTypeForCallableMethods(Type type)
397+
static Dictionary<string, (MethodInfo, Type[])> ScanTypeForCallableMethods([DynamicallyAccessedMembers(JSInvokable)] Type type)
398398
{
399399
var result = new Dictionary<string, (MethodInfo, Type[])>(StringComparer.Ordinal);
400400

@@ -499,11 +499,16 @@ private static Assembly GetRequiredLoadedAssembly(AssemblyKey assemblyKey)
499499
?? throw new ArgumentException($"There is no loaded assembly with the name '{assemblyKey.AssemblyName}'.");
500500
}
501501

502-
private static void ClearCache(Type[]? _)
502+
// don't point the MetadataUpdateHandlerAttribute at the DotNetDispatcher class, since the attribute has
503+
// DynamicallyAccessedMemberTypes.All. This causes unnecessary trim warnings on the non-MetadataUpdateHandler methods.
504+
internal static class MetadataUpdateHandler
503505
{
504-
_cachedMethodsByAssembly.Clear();
505-
_cachedMethodsByType.Clear();
506-
_cachedConvertToTaskByType.Clear();
506+
public static void ClearCache(Type[]? _)
507+
{
508+
_cachedMethodsByAssembly.Clear();
509+
_cachedMethodsByType.Clear();
510+
_cachedConvertToTaskByType.Clear();
511+
}
507512
}
508513

509514
private readonly struct AssemblyKey : IEquatable<AssemblyKey>

src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetObjectReferenceJsonConverter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Diagnostics.CodeAnalysis;
45
using System.Text.Json;
56
using System.Text.Json.Serialization;
7+
using static Microsoft.AspNetCore.Internal.LinkerFlags;
68

79
namespace Microsoft.JSInterop.Infrastructure;
810

9-
internal sealed class DotNetObjectReferenceJsonConverter<TValue> : JsonConverter<DotNetObjectReference<TValue>> where TValue : class
11+
internal sealed class DotNetObjectReferenceJsonConverter<[DynamicallyAccessedMembers(JSInvokable)] TValue> : JsonConverter<DotNetObjectReference<TValue>> where TValue : class
1012
{
1113
public DotNetObjectReferenceJsonConverter(JSRuntime jsRuntime)
1214
{

src/JSInterop/Microsoft.JSInterop/src/JSRuntime.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ internal long BeginTransmittingStream(DotNetStreamReference dotNetStreamReferenc
290290
return streamId;
291291
}
292292

293-
internal long TrackObjectReference<TValue>(DotNetObjectReference<TValue> dotNetObjectReference) where TValue : class
293+
internal long TrackObjectReference<[DynamicallyAccessedMembers(JSInvokable)] TValue>(DotNetObjectReference<TValue> dotNetObjectReference) where TValue : class
294294
{
295295
if (dotNetObjectReference == null)
296296
{

src/JSInterop/Microsoft.JSInterop/src/Microsoft.JSInterop.WarningSuppressions.xml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<linker>
3-
<assembly fullname="Microsoft.JSInterop, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
3+
<assembly fullname="Microsoft.JSInterop, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
44
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
55
<argument>ILLink</argument>
66
<argument>IL2026</argument>
@@ -39,9 +39,9 @@
3939
</attribute>
4040
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
4141
<argument>ILLink</argument>
42-
<argument>IL2060</argument>
42+
<argument>IL2055</argument>
4343
<property name="Scope">member</property>
44-
<property name="Target">M:Microsoft.JSInterop.Infrastructure.DotNetDispatcher.&lt;&gt;c.&lt;GetTaskByType&gt;b__14_0(System.Type,System.Reflection.MethodInfo)</property>
44+
<property name="Target">M:Microsoft.JSInterop.Infrastructure.DotNetObjectReferenceJsonConverterFactory.CreateConverter(System.Type,System.Text.Json.JsonSerializerOptions)</property>
4545
</attribute>
4646
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
4747
<argument>ILLink</argument>
@@ -67,5 +67,11 @@
6767
<property name="Scope">member</property>
6868
<property name="Target">M:Microsoft.JSInterop.JSRuntimeExtensions.&lt;InvokeAsync&gt;d__4`1.MoveNext</property>
6969
</attribute>
70+
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
71+
<argument>ILLink</argument>
72+
<argument>IL2111</argument>
73+
<property name="Scope">member</property>
74+
<property name="Target">M:Microsoft.JSInterop.Infrastructure.DotNetDispatcher.GetCachedMethodInfo(Microsoft.JSInterop.Infrastructure.IDotNetObjectReference,System.String)</property>
75+
</attribute>
7076
</assembly>
71-
</linker>
77+
</linker>

src/Shared/LinkerFlags.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,9 @@ internal static class LinkerFlags
1616
/// Flags for a component
1717
/// </summary>
1818
public const DynamicallyAccessedMemberTypes Component = DynamicallyAccessedMemberTypes.All;
19+
20+
/// <summary>
21+
/// Flags for a JSInvokable type.
22+
/// </summary>
23+
public const DynamicallyAccessedMemberTypes JSInvokable = DynamicallyAccessedMemberTypes.PublicMethods;
1924
}

0 commit comments

Comments
 (0)