[protocolbuffers/protobuf][C#] 修复修剪警告

2024-05-11 57 views
4

背景:.NET 6 引入了修剪分析和警告。当 Google.Protobuf 包含在应用程序中并启用修剪时,应用程序将从 Google.Protobuf 获取与修剪相关的警告列表。这些通常是代码中使用反射的位置,但类型可能已在构建时被修剪。在运行时修剪后,使用这些代码区域可能会失败。

有关详细信息,请参阅https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming/prepare-libraries-for-trimming

此 PR 通过添加修剪注释修复了 Google.Protobuf 的修剪警告。它们要么保留类型信息,以便修剪器可以做出更好的决策,要么警告 Google.Protobuf 的调用者该 API 与修剪不兼容。

我测试了所有修剪警告都是通过使用 Google.Protobuf 和 grpc-dotnet 存储库中的测试应用程序来修复的。

另外,我更新了测试项目以使用 netcoreapp3.1。以前的目标 netcoreapp2.1 不再受支持,并且构建会生成警告。

抄送@jtattermusch @captainsafia

回答

5

你是怎么找到这些的?

我用 RC1 测试了构建警告。 RC2 和最终版中是否添加了更多警告?

4

我通过从项目中的 LinkedTestClient 进行修剪来进行测试dotnet-grpc,并将包引用更改为项目引用。我也直到后来才设置 IsTrimmable,因为不设置 IsTrimmable 将扫描整个程序集,以防万一。

4

@MichalStrehovsky @agocke @jkotas 所有警告均已修复。

我不确定的一件事是这段代码:https://github.com/protocolbuffers/protobuf/blob/7ccf4d8f67878a6ceb2184df279478cb3314372b/csharp/src/Google.Protobuf/JsonFormatter.cs#L884-L898

枚举类型在代码生成的描述符代码中指定 - https://github.com/protocolbuffers/protobuf/blob/7ccf4d8f67878a6ceb2184df279478cb3314372b/csharp/src/Google.Protobuf/Reflection/GenerateClrTypeInfo.cs#L81-L91 - 不幸的是,它是一个的数组Type,因此不允许使用动态成员属性。您是否考虑过启用该属性Type[]

6

不幸的是,数组的问题并不是我们不能允许该属性,而是属性代表了跟踪变量的能力,而跟踪数组的各个元素可能会太困难/成本太高。

也就是说,这是对未来进行调查的改进。

9

您需要更新https://github.com/protocolbuffers/protobuf/blob/13d559beb6967033a467a7517c35d8ad970f8afb/csharp/install_dotnet_sdk.ps1#L19

https://github.com/protocolbuffers/protobuf/blob/13d559beb6967033a467a7517c35d8ad970f8afb/kokoro/linux/dockerfile/test/csharp/Dockerfile#L35(你需要我为你推送那个dockerfile)。

理想情况下,我们会有一个单独的 PR 来升级预安装的 SDK 并切换到 netcoreapp3.1 目标(除非安装了 3.1 运行时,否则它们不会运行),之后我们可以查看此 PR 中的实际更改。

3

重新调整基础。

6

似乎测试失败了。

4

@jtattermusch 已修复。

7

nit:Makefile.am 需要更新

++ '[' '!' -z 'csharp/src/Google.Protobuf/Compatibility/UnconditionalSuppressMessageAttribute.cs csharp/src/Google.Protobuf/Compatibility/RequiresUnreferencedCodeAttribute.cs csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMembersAttribute.cs csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMemberTypes.cs ' ']'
++ echo 'Missing files in EXTRA_DIST: csharp/src/Google.Protobuf/Compatibility/UnconditionalSuppressMessageAttribute.cs csharp/src/Google.Protobuf/Compatibility/RequiresUnreferencedCodeAttribute.cs csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMembersAttribute.cs csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMemberTypes.cs '
Missing files in EXTRA_DIST: csharp/src/Google.Protobuf/Compatibility/UnconditionalSuppressMessageAttribute.cs csharp/src/Google.Protobuf/Compatibility/RequiresUnreferencedCodeAttribute.cs csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMembersAttribute.cs csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMemberTypes.cs
++ exit 1

https://source.cloud.google.com/results/inspirations/503d13e5-df5f-416e-8974-3b2a19a427ec/log

1

FTR 因为我不知道你测试的“测试应用程序”是什么,所以我自己做了一个小实验。我尝试修剪 Google.Protobuf.Test 二进制文件,因为 Google.Protobuf.Test 根据定义练习了大量 Google.Protobuf API。需要进行一些调整(升级一些 nuget 依赖项并删除 CustomOptionsTest.cs,现在“不支持”修剪),但我能够运行dotnet publish -r osx-x64 --self-contained -f net60 -p:PublishTrimmed=true Google.Protobuf.Test

该实验给了我这些警告:

/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs(113,58): Trim analysis warning IL2077: Google.Protobuf.Compatibility.TypeExtensionsTest.<>c__DisplayClass16_0.<GetMethod_Ambiguous>b__0(): 'target' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'Google.Protobuf.Compatibility.TypeExtensions.GetMethod(Type,String)'. The field 'System.Type Google.Protobuf.Compatibility.TypeExtensionsTest/<>c__DisplayClass16_0::type' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj]
/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs(630,13): Trim analysis warning IL2067: Google.Protobuf.JsonFormatterTest.Wrappers_Standalone(Type,Object,String): '#0' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicParameterlessConstructor' in call to 'System.Object System.Activator::CreateInstance(System.Type)'. The parameter 'wrapperType' of method 'Google.Protobuf.JsonFormatterTest.Wrappers_Standalone(Type,Object,String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj]
/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/JsonParserTest.cs(151,13): Trim analysis warning IL2067: Google.Protobuf.JsonParserTest.Wrappers_Standalone(Type,String,Object): '#0' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicParameterlessConstructor' in call to 'System.Object System.Activator::CreateInstance(System.Type)'. The parameter 'wrapperType' of method 'Google.Protobuf.JsonParserTest.Wrappers_Standalone(Type,String,Object)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj]
/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/JsonParserTest.cs(152,13): Trim analysis warning IL2067: Google.Protobuf.JsonParserTest.Wrappers_Standalone(Type,String,Object): '#0' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicParameterlessConstructor' in call to 'System.Object System.Activator::CreateInstance(System.Type)'. The parameter 'wrapperType' of method 'Google.Protobuf.JsonParserTest.Wrappers_Standalone(Type,String,Object)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj]
/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs(105,13): Trim analysis warning IL2067: Google.Protobuf.Compatibility.TypeExtensionsTest.GetMethod_NoSuchMethod(Type,String): 'target' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'Google.Protobuf.Compatibility.TypeExtensions.GetMethod(Type,String)'. The parameter 'type' of method 'Google.Protobuf.Compatibility.TypeExtensionsTest.GetMethod_NoSuchMethod(Type,String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj]
/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs(95,13): Trim analysis warning IL2067: Google.Protobuf.Compatibility.TypeExtensionsTest.GetMethod_Success(Type,String): 'target' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'Google.Protobuf.Compatibility.TypeExtensions.GetMethod(Type,String)'. The parameter 'type' of method 'Google.Protobuf.Compatibility.TypeExtensionsTest.GetMethod_Success(Type,String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj]
/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs(85,13): Trim analysis warning IL2067: Google.Protobuf.Compatibility.TypeExtensionsTest.GetProperty_NoSuchProperty(Type,String): 'target' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicProperties', 'DynamicallyAccessedMemberTypes.NonPublicProperties' in call to 'Google.Protobuf.Compatibility.TypeExtensions.GetProperty(Type,String)'. The parameter 'type' of method 'Google.Protobuf.Compatibility.TypeExtensionsTest.GetProperty_NoSuchProperty(Type,String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj]
/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs(75,13): Trim analysis warning IL2067: Google.Protobuf.Compatibility.TypeExtensionsTest.GetProperty_Success(Type,String): 'target' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicProperties', 'DynamicallyAccessedMemberTypes.NonPublicProperties' in call to 'Google.Protobuf.Compatibility.TypeExtensions.GetProperty(Type,String)'. The parameter 'type' of method 'Google.Protobuf.Compatibility.TypeExtensionsTest.GetProperty_Success(Type,String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/Users/jtattermusch/github/protobuf/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj]
....
[I removed warnings unrelated to Google.Protobuf assembly]
5

FTR 因为我不知道你测试的“测试应用程序”是什么,所以我自己做了一个小实验。

我使用这个应用程序进行了测试:https://github.com/grpc/grpc-dotnet/tree/dce1ef72d8b88a380136a699a1fb26ca3793a597/testassets/LinkerTestsClient(尽管我在测试时修改了它以引用Google.Protobuf源代码)

有一个 grpc-dotnet 单元测试,它通过修剪发布应用程序,然后执行它:https://github.com/grpc/grpc-dotnet/blob/82dec0ff513059786de5254e62d71c5f55e0ed5b/test/FunctionalTests/Linker/LinkerTests.cs

实际上测试修剪确实很困难,因为您不能在单个应用程序中进行多个测试,因为每个测试都可能包含类型和成员,否则如果单独运行测试则不会包含这些类型和成员。

但是,修剪警告不应受此影响。它分析整个程序集,而不仅仅是应用程序使用的部件。

该实验给了我这些警告:

您列出的警告来自测试项目。

5

nit:Makefile.am 需要更新

固定的

4

我们不知道 Google.Protobuf 修剪是否能在现实生活中的应用程序中可靠地工作(我们只尝试了一个小型测试项目)

有一个用于单元测试的小测试项目,但在实际应用程序中,有很多人在 Blazor 中使用 Trimming + gRPC + Google.Protobuf。

JSON 功能是否可以与修剪一起使用仍然是一个悬而未决的问题。

因此,目前在提及此更改时,我不会提出“Google.Protobuf 现在支持修剪”之类的说法。我认为目前的情况更像是“支持修剪的初步工作已经完成,Google.Protobuf 可能运行良好 - 但用户应该仔细测试以确保不存在任何回归”。

没关系。这里的目标是消除警告。