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

Enable client library trim warnings #849

Merged
merged 2 commits into from
Oct 8, 2024
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
6 changes: 6 additions & 0 deletions samples/ChatApp/ChatApp.Console/ChatApp.Console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\ChatApp.Unity\Assets\Scripts\Generated\MessagePack.Generated.cs" Link="MessagePack.Generated.cs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\MagicOnion.Client.SourceGenerator\MagicOnion.Client.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\..\..\src\MagicOnion.Client\MagicOnion.Client.csproj" />
Expand Down
17 changes: 15 additions & 2 deletions samples/ChatApp/ChatApp.Console/Program.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
// See https://aka.ms/new-console-template for more information

using System.Runtime.CompilerServices;
using ChatApp.Shared.Hubs;
using ChatApp.Shared.MessagePackObjects;
using Grpc.Net.Client;
using MagicOnion.Client;
using MessagePack;
using MessagePack.Resolvers;

var channel = GrpcChannel.ForAddress("http://localhost:5000");
if (!RuntimeFeature.IsDynamicCodeSupported)
{
// Running on Native AOT
StaticCompositeResolver.Instance.Register(
BuiltinResolver.Instance,
PrimitiveObjectResolver.Instance,
MagicOnionGeneratedClientInitializer.Resolver,
MessagePack.Resolvers.GeneratedResolver.Instance
);
MessagePackSerializer.DefaultOptions = MessagePackSerializer.DefaultOptions.WithResolver(StaticCompositeResolver.Instance);
}

var channel = GrpcChannel.ForAddress("http://localhost:5000");
var sessionId = Guid.NewGuid();
Console.WriteLine("Connecting...");
var hub = await StreamingHubClient.ConnectAsync<IChatHub, IChatHubReceiver>(channel, new ChatHubReceiver(sessionId));
Expand All @@ -30,7 +44,6 @@
[MagicOnionClientGeneration(typeof(IChatHub))]
partial class MagicOnionGeneratedClientInitializer;


class ChatHubReceiver(Guid sessionId) : IChatHubReceiver
{
public void OnJoin(string name)
Expand Down
6 changes: 3 additions & 3 deletions src/MagicOnion.Abstractions/Internal/Box.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ internal Box(T value)
Value = value;
}

public bool Equals(Box<T> other)
public bool Equals(Box<T>? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return EqualityComparer<T>.Default.Equals(Value, other.Value);
}

public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return ReferenceEquals(this, obj) || obj is Box<T> other && Equals(other);
}

public override int GetHashCode()
{
return EqualityComparer<T>.Default.GetHashCode(Value);
return EqualityComparer<T>.Default.GetHashCode(Value!);
}

public static bool operator ==(Box<T> valueA, Box<T> valueB)
Expand Down
3 changes: 2 additions & 1 deletion src/MagicOnion.Abstractions/MagicOnion.Abstractions.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>

<LangVersion>$(_LangVersionUnityBaseline)</LangVersion>
<Nullable>enable</Nullable>
<IsTrimmable Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</IsTrimmable>

<PackageId>MagicOnion.Abstractions</PackageId>
<Description>MagicOnion interfaces and abstractions for server and client.
Expand Down
4 changes: 2 additions & 2 deletions src/MagicOnion.Abstractions/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ MagicOnion.IgnoreAttribute
MagicOnion.IgnoreAttribute.IgnoreAttribute() -> void
MagicOnion.Internal.Box
MagicOnion.Internal.Box<T>
MagicOnion.Internal.Box<T>.Equals(MagicOnion.Internal.Box<T>! other) -> bool
MagicOnion.Internal.Box<T>.Equals(MagicOnion.Internal.Box<T>? other) -> bool
MagicOnion.Internal.IAsyncClientStreamingCallWrapper<TRequest, TResponse>
MagicOnion.Internal.IAsyncClientStreamingCallWrapper<TRequest, TResponse>.RequestStream.get -> Grpc.Core.IClientStreamWriter<TRequest>!
MagicOnion.Internal.IAsyncClientStreamingCallWrapper<TRequest, TResponse>.ResponseAsync.get -> System.Threading.Tasks.Task<TResponse>!
Expand Down Expand Up @@ -155,7 +155,7 @@ MagicOnion.UnaryResult<TResponse>.UnaryResult() -> void
MagicOnion.UnaryResult<TResponse>.UnaryResult(System.Threading.Tasks.Task<MagicOnion.Client.IResponseContext<TResponse>!>! response) -> void
MagicOnion.UnaryResult<TResponse>.UnaryResult(System.Threading.Tasks.Task<TResponse>! rawTaskValue) -> void
MagicOnion.UnaryResult<TResponse>.UnaryResult(TResponse rawValue) -> void
override MagicOnion.Internal.Box<T>.Equals(object! obj) -> bool
override MagicOnion.Internal.Box<T>.Equals(object? obj) -> bool
override MagicOnion.Internal.Box<T>.GetHashCode() -> int
readonly MagicOnion.DynamicArgumentTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>.Item1 -> T1
readonly MagicOnion.DynamicArgumentTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>.Item10 -> T10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ internal Box(T value)
Value = value;
}

public bool Equals(Box<T> other)
public bool Equals(Box<T>? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return EqualityComparer<T>.Default.Equals(Value, other.Value);
}

public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return ReferenceEquals(this, obj) || obj is Box<T> other && Equals(other);
}

public override int GetHashCode()
{
return EqualityComparer<T>.Default.GetHashCode(Value);
return EqualityComparer<T>.Default.GetHashCode(Value!);
}

public static bool operator ==(Box<T> valueA, Box<T> valueB)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.Diagnostics.CodeAnalysis;
using MagicOnion.Internal.Reflection;

namespace MagicOnion.Client.DynamicClient
{
[RequiresUnreferencedCode(nameof(DynamicClientAssemblyHolder) + " is incompatible with trimming and Native AOT.")]
#if ENABLE_SAVE_ASSEMBLY
public
#else
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using Grpc.Core;
using MagicOnion.Client.Internal;
using MagicOnion.Serialization;
Expand All @@ -20,6 +20,7 @@ protected static class KnownTypes
}
}

[RequiresUnreferencedCode(nameof(DynamicClientBuilder<T>) + " is incompatible with trimming and Native AOT.")]
internal class DynamicClientBuilder<T> : DynamicClientBuilder
where T : IService<T>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public bool TryGetFactory<T>([NotNullWhen(true)] out MagicOnionClientFactoryDele
/// <summary>
/// Provides to get a MagicOnionClient factory of the specified service type. The provider is backed by DynamicMagicOnionClientBuilder.
/// </summary>
[RequiresUnreferencedCode(nameof(DynamicMagicOnionClientFactoryProvider) + " is incompatible with trimming and Native AOT.")]
public class DynamicMagicOnionClientFactoryProvider : IMagicOnionClientFactoryProvider
{
public static IMagicOnionClientFactoryProvider Instance { get; } = new DynamicMagicOnionClientFactoryProvider();
Expand All @@ -30,6 +31,7 @@ public bool TryGetFactory<T>([NotNullWhen(true)] out MagicOnionClientFactoryDele
return true;
}

[RequiresUnreferencedCode(nameof(DynamicMagicOnionClientFactoryProvider) + "." + nameof(Cache<T>) + " is incompatible with trimming and Native AOT.")]
static class Cache<T> where T : IService<T>
{
public static readonly MagicOnionClientFactoryDelegate<T> Factory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using MessagePack;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
Expand All @@ -14,6 +15,7 @@

namespace MagicOnion.Client.DynamicClient
{
[RequiresUnreferencedCode(nameof(DynamicStreamingHubClientAssemblyHolder) + " is incompatible with trimming and Native AOT.")]
#if ENABLE_SAVE_ASSEMBLY
public
#else
Expand Down Expand Up @@ -41,6 +43,7 @@ public static AssemblyBuilder Save()
#endif
}

[RequiresUnreferencedCode(nameof(DynamicStreamingHubClientBuilder<TStreamingHub, TReceiver>) + " is incompatible with trimming and Native AOT.")]
#if ENABLE_SAVE_ASSEMBLY
public
#else
Expand Down Expand Up @@ -709,6 +712,7 @@ static void DefineMethodsFireAndForget(TypeBuilder typeBuilder, Type interfaceTy
}
}

[RequiresUnreferencedCode(nameof(MethodInfoCache) + " is incompatible with trimming and Native AOT.")]
static class MethodInfoCache
{
// ReSharper disable StaticMemberInGenericType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public bool TryGetFactory<TStreamingHub, TReceiver>([NotNullWhen(true)] out Stre
}
}

[RequiresUnreferencedCode(nameof(DynamicStreamingHubClientFactoryProvider) + " is incompatible with trimming and Native AOT.")]
public class DynamicStreamingHubClientFactoryProvider : IStreamingHubClientFactoryProvider
{
public static IStreamingHubClientFactoryProvider Instance { get; } = new DynamicStreamingHubClientFactoryProvider();
Expand All @@ -27,6 +28,7 @@ public bool TryGetFactory<TStreamingHub, TReceiver>([NotNullWhen(true)] out Stre
return true;
}

[RequiresUnreferencedCode(nameof(DynamicStreamingHubClientFactoryProvider) + "." + nameof(Cache<TStreamingHub, TReceiver>) + " is incompatible with trimming and Native AOT.")]
static class Cache<TStreamingHub, TReceiver> where TStreamingHub : IStreamingHub<TStreamingHub, TReceiver>
{
public static readonly StreamingHubClientFactoryDelegate<TStreamingHub, TReceiver> Factory
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Grpc.Core;
using MagicOnion.Client.Internal;

namespace MagicOnion.Client.DynamicClient
{
[RequiresUnreferencedCode(nameof(RawMethodInvokerTypes) + " is incompatible with trimming and Native AOT.")]
internal static class RawMethodInvokerTypes
{
static readonly MethodInfo create_RefType_RefType = typeof(RawMethodInvoker).GetMethod(nameof(RawMethodInvoker.Create_RefType_RefType), BindingFlags.Static | BindingFlags.Public)!;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
Expand All @@ -9,6 +10,7 @@

namespace MagicOnion.Client.DynamicClient
{
[RequiresUnreferencedCode(nameof(ServiceClientDefinition) + " is incompatible with trimming and Native AOT.")]
internal class ServiceClientDefinition
{
public Type ServiceInterfaceType { get; }
Expand All @@ -20,6 +22,7 @@ public ServiceClientDefinition(Type serviceInterfaceType, IReadOnlyList<MagicOni
Methods = methods;
}

[RequiresUnreferencedCode(nameof(MagicOnionServiceMethodInfo) + " is incompatible with trimming and Native AOT.")]
public class MagicOnionServiceMethodInfo
{
public MethodType MethodType { get; }
Expand Down Expand Up @@ -69,7 +72,7 @@ public static MagicOnionServiceMethodInfo Create(Type serviceType, MethodInfo me
return method;
}

private void Verify()
void Verify()
{
switch (MethodType)
{
Expand All @@ -91,7 +94,7 @@ private void Verify()
}
}

private static (MethodType MethodType, Type? RequestType, Type ResponseType) GetMethodTypeAndResponseTypeFromMethod(MethodInfo methodInfo)
static (MethodType MethodType, Type? RequestType, Type ResponseType) GetMethodTypeAndResponseTypeFromMethod(MethodInfo methodInfo)
{
const string UnsupportedReturnTypeErrorMessage =
"The method of a service must return 'UnaryResult<T>', 'Task<ClientStreamingResult<TRequest, TResponse>>', 'Task<ServerStreamingResult<T>>' or 'DuplexStreamingResult<TRequest, TResponse>'.";
Expand Down Expand Up @@ -171,7 +174,7 @@ public static ServiceClientDefinition CreateFromType<T>()
return new ServiceClientDefinition(typeof(T), GetServiceMethods(typeof(T)));
}

private static IReadOnlyList<MagicOnionServiceMethodInfo> GetServiceMethods(Type serviceType)
static IReadOnlyList<MagicOnionServiceMethodInfo> GetServiceMethods(Type serviceType)
{
return serviceType
.GetInterfaces()
Expand Down Expand Up @@ -209,7 +212,7 @@ private static IReadOnlyList<MagicOnionServiceMethodInfo> GetServiceMethods(Type
/// </summary>
/// <param name="methodInfo"></param>
/// <returns></returns>
private static Type GetRequestTypeFromMethod(MethodInfo methodInfo)
static Type GetRequestTypeFromMethod(MethodInfo methodInfo)
{
var parameterTypes = methodInfo.GetParameters().Select(x => x.ParameterType).ToArray();
switch (parameterTypes.Length)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using MagicOnion.Server.Hubs;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;

namespace MagicOnion.Internal
{
[RequiresUnreferencedCode("BroadcastHelper is incompatible with trimming.")]
internal static class BroadcasterHelper
{
internal static Type[] DynamicArgumentTupleTypes { get; } = typeof(DynamicArgumentTuple<,>)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using MessagePack;
using System;
using System.Buffers;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;

Expand All @@ -10,13 +11,7 @@ namespace MagicOnion.Internal
// invoke from dynamic methods so must be public
internal static class MagicOnionMarshallers
{
static readonly Type[] dynamicArgumentTupleTypes = typeof(DynamicArgumentTuple<,>).GetTypeInfo().Assembly
.GetTypes()
.Where(x => x.Name.StartsWith("DynamicArgumentTuple") && !x.Name.Contains("Formatter"))
.OrderBy(x => x.GetGenericArguments().Length)
.ToArray();

internal static Marshaller<StreamingHubPayload> StreamingHubMarshaller { get; } = new(
public static Marshaller<StreamingHubPayload> StreamingHubMarshaller { get; } = new(
serializer: static (payload, context) =>
{
context.SetPayloadLength(payload.Length);
Expand All @@ -32,7 +27,8 @@ internal static class MagicOnionMarshallers
}
);

internal static Type CreateRequestType(ParameterInfo[] parameters)
[RequiresUnreferencedCode(nameof(MagicOnionMarshallers) + "." + nameof(CreateRequestType) + " is incompatible with trimming and Native AOT.")]
public static Type CreateRequestType(ParameterInfo[] parameters)
{
if (parameters.Length == 0)
{
Expand All @@ -50,18 +46,29 @@ internal static Type CreateRequestType(ParameterInfo[] parameters)
else
{
// start from T2
var tupleTypeBase = dynamicArgumentTupleTypes[parameters.Length - 2];
var tupleTypeBase = DynamicArgumentTupleTypesCache.Types[parameters.Length - 2];
var t = tupleTypeBase.MakeGenericType(parameters.Select(x => x.ParameterType).ToArray());
return t;
}
}

[RequiresUnreferencedCode(nameof(MagicOnionMarshallers) + "." + nameof(InstantiateDynamicArgumentTuple) + " is incompatible with trimming and Native AOT.")]
public static object InstantiateDynamicArgumentTuple(Type[] typeParameters, object[] arguments)
{
// start from T2
var tupleTypeBase = dynamicArgumentTupleTypes[arguments.Length - 2];
var tupleTypeBase = DynamicArgumentTupleTypesCache.Types[arguments.Length - 2];
return Activator.CreateInstance(tupleTypeBase.MakeGenericType(typeParameters), arguments)!;
}

[RequiresUnreferencedCode(nameof(DynamicArgumentTupleTypesCache) + " is incompatible with trimming and Native AOT.")]
static class DynamicArgumentTupleTypesCache
{
public static readonly Type[] Types = typeof(DynamicArgumentTuple<,>).GetTypeInfo().Assembly
.GetTypes()
.Where(x => x.Name.StartsWith("DynamicArgumentTuple") && !x.Name.Contains("Formatter"))
.OrderBy(x => x.GetGenericArguments().Length)
.ToArray();
}
}

}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading