Skip to content

Commit 06368ad

Browse files
authored
Merge pull request #1196 from microsoft/NativeAOT
Add attributes for NativeAOT safety
2 parents 8648587 + 3f58494 commit 06368ad

23 files changed

+704
-95
lines changed

StreamJsonRpc.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{F446B894-5
3838
test\Directory.Build.targets = test\Directory.Build.targets
3939
EndProjectSection
4040
EndProject
41+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeAOTCompatibility.Test", "test\NativeAOTCompatibility.Test\NativeAOTCompatibility.Test.csproj", "{1837EED6-4236-09AA-AEAA-0B8F5C35813E}"
42+
EndProject
4143
Global
4244
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4345
Debug|Any CPU = Debug|Any CPU
@@ -60,6 +62,10 @@ Global
6062
{5936CF62-A59D-4E5C-9EE4-5E8BAFA9F215}.Debug|Any CPU.Build.0 = Debug|Any CPU
6163
{5936CF62-A59D-4E5C-9EE4-5E8BAFA9F215}.Release|Any CPU.ActiveCfg = Release|Any CPU
6264
{5936CF62-A59D-4E5C-9EE4-5E8BAFA9F215}.Release|Any CPU.Build.0 = Release|Any CPU
65+
{1837EED6-4236-09AA-AEAA-0B8F5C35813E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
66+
{1837EED6-4236-09AA-AEAA-0B8F5C35813E}.Debug|Any CPU.Build.0 = Debug|Any CPU
67+
{1837EED6-4236-09AA-AEAA-0B8F5C35813E}.Release|Any CPU.ActiveCfg = Release|Any CPU
68+
{1837EED6-4236-09AA-AEAA-0B8F5C35813E}.Release|Any CPU.Build.0 = Release|Any CPU
6369
EndGlobalSection
6470
GlobalSection(SolutionProperties) = preSolution
6571
HideSolutionNode = FALSE
@@ -69,6 +75,7 @@ Global
6975
{8BF355B2-E3B0-4615-BFC1-7563EADC4F8B} = {F446B894-56AA-4653-ADC0-5FFC911C9C13}
7076
{CEF0F77F-19EB-4C76-A050-854984BB0364} = {F446B894-56AA-4653-ADC0-5FFC911C9C13}
7177
{5936CF62-A59D-4E5C-9EE4-5E8BAFA9F215} = {F446B894-56AA-4653-ADC0-5FFC911C9C13}
78+
{1837EED6-4236-09AA-AEAA-0B8F5C35813E} = {F446B894-56AA-4653-ADC0-5FFC911C9C13}
7279
EndGlobalSection
7380
GlobalSection(ExtensibilityGlobals) = postSolution
7481
SolutionGuid = {4946F7E7-0619-414B-BE56-DDF0261CA8A9}

azure-pipelines/build.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ jobs:
199199
parameters:
200200
Is1ESPT: ${{ parameters.Is1ESPT }}
201201
RunTests: ${{ parameters.RunTests }}
202+
osRID: win
202203
IsOptProf: ${{ parameters.IsOptProf }}
203204

204205
- ${{ if and(parameters.EnableDotNetFormatCheck, not(parameters.EnableLinuxBuild)) }}:
@@ -243,6 +244,7 @@ jobs:
243244
parameters:
244245
Is1ESPT: ${{ parameters.Is1ESPT }}
245246
RunTests: ${{ parameters.RunTests }}
247+
osRID: linux
246248
- ${{ if parameters.EnableDotNetFormatCheck }}:
247249
- script: dotnet format --verify-no-changes
248250
displayName: 💅 Verify formatted code
@@ -277,6 +279,7 @@ jobs:
277279
parameters:
278280
Is1ESPT: ${{ parameters.Is1ESPT }}
279281
RunTests: ${{ parameters.RunTests }}
282+
osRID: osx
280283

281284
- job: WrapUp
282285
dependsOn:

azure-pipelines/dotnet.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
parameters:
22
- name: RunTests
3+
- name: osRID
4+
type: string
35
- name: IsOptProf
46
type: boolean
57
default: false
@@ -40,6 +42,10 @@ steps:
4042
- script: dotnet pack src\VSInsertionMetadata -c $(BuildConfiguration) -warnaserror /bl:"$(Build.ArtifactStagingDirectory)/build_logs/VSInsertion-Pack.binlog"
4143
displayName: 🔧 dotnet pack VSInsertionMetadata
4244

45+
- script: dotnet publish -r ${{ parameters.osRID }}-x64 -warnaserror
46+
displayName: 🧪 NativeAOT test
47+
workingDirectory: test/NativeAOTCompatibility.Test
48+
4349
- powershell: tools/variables/_define.ps1
4450
failOnStderr: true
4551
displayName: ⚙ Update pipeline variables based on build outputs

src/StreamJsonRpc/HeaderDelimitedMessageHandler.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Buffers;
55
using System.Buffers.Text;
6+
using System.Diagnostics.CodeAnalysis;
67
using System.IO.Pipelines;
78
using System.Net.Http.Headers;
89
using System.Runtime.CompilerServices;
@@ -97,6 +98,7 @@ public HeaderDelimitedMessageHandler(Stream duplexStream, IJsonRpcMessageFormatt
9798
/// Initializes a new instance of the <see cref="HeaderDelimitedMessageHandler"/> class.
9899
/// </summary>
99100
/// <param name="duplexStream">The stream to use for transmitting and receiving messages.</param>
101+
[RequiresDynamicCode(RuntimeReasons.Formatters), RequiresUnreferencedCode(RuntimeReasons.Formatters)]
100102
public HeaderDelimitedMessageHandler(Stream duplexStream)
101103
: this(duplexStream, duplexStream)
102104
{
@@ -107,6 +109,7 @@ public HeaderDelimitedMessageHandler(Stream duplexStream)
107109
/// </summary>
108110
/// <param name="sendingStream">The stream to use for transmitting messages.</param>
109111
/// <param name="receivingStream">The stream to use for receiving messages.</param>
112+
[RequiresDynamicCode(RuntimeReasons.Formatters), RequiresUnreferencedCode(RuntimeReasons.Formatters)]
110113
public HeaderDelimitedMessageHandler(Stream? sendingStream, Stream? receivingStream)
111114
: this(sendingStream, receivingStream, new JsonMessageFormatter())
112115
{

src/StreamJsonRpc/JsonMessageFormatter.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace StreamJsonRpc;
2626
/// <remarks>
2727
/// Each instance of this class may only be used with a single <see cref="JsonRpc" /> instance.
2828
/// </remarks>
29+
[RequiresDynamicCode(RuntimeReasons.Formatters), RequiresUnreferencedCode(RuntimeReasons.Formatters)]
2930
public class JsonMessageFormatter : FormatterBase, IJsonRpcAsyncMessageTextFormatter, IJsonRpcMessageFactory
3031
{
3132
/// <summary>
@@ -1009,6 +1010,7 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer
10091010
/// <summary>
10101011
/// Converts a progress token to an <see cref="IProgress{T}"/>.
10111012
/// </summary>
1013+
[RequiresDynamicCode(RuntimeReasons.CloseGenerics)]
10121014
private class JsonProgressServerConverter : JsonConverter
10131015
{
10141016
private readonly JsonMessageFormatter formatter;
@@ -1042,6 +1044,7 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer
10421044
/// <summary>
10431045
/// Converts an enumeration token to an <see cref="IAsyncEnumerable{T}"/>.
10441046
/// </summary>
1047+
[RequiresDynamicCode(RuntimeReasons.CloseGenerics)]
10451048
private class AsyncEnumerableConsumerConverter : JsonConverter
10461049
{
10471050
private static readonly MethodInfo ReadJsonOpenGenericMethod = typeof(AsyncEnumerableConsumerConverter).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic).Single(m => m.Name == nameof(ReadJson) && m.IsGenericMethod);
@@ -1062,7 +1065,7 @@ internal AsyncEnumerableConsumerConverter(JsonMessageFormatter jsonMessageFormat
10621065
return null;
10631066
}
10641067

1065-
Type? iface = TrackerHelpers<IAsyncEnumerable<int>>.FindInterfaceImplementedBy(objectType);
1068+
Type? iface = TrackerHelpers.FindIAsyncEnumerableInterfaceImplementedBy(objectType);
10661069
Assumes.NotNull(iface);
10671070
MethodInfo genericMethod = ReadJsonOpenGenericMethod.MakeGenericMethod(iface.GenericTypeArguments[0]);
10681071
try
@@ -1100,6 +1103,7 @@ private IAsyncEnumerable<T> ReadJson<T>(JsonReader reader, JsonSerializer serial
11001103
/// <summary>
11011104
/// Converts an instance of <see cref="IAsyncEnumerable{T}"/> to an enumeration token.
11021105
/// </summary>
1106+
[RequiresDynamicCode(RuntimeReasons.CloseGenerics)]
11031107
private class AsyncEnumerableGeneratorConverter : JsonConverter
11041108
{
11051109
private static readonly MethodInfo WriteJsonOpenGenericMethod = typeof(AsyncEnumerableGeneratorConverter).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Single(m => m.Name == nameof(WriteJson) && m.IsGenericMethod);
@@ -1120,7 +1124,7 @@ internal AsyncEnumerableGeneratorConverter(JsonMessageFormatter jsonMessageForma
11201124

11211125
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
11221126
{
1123-
Type? iface = TrackerHelpers<IAsyncEnumerable<int>>.FindInterfaceImplementedBy(value!.GetType());
1127+
Type? iface = TrackerHelpers.FindIAsyncEnumerableInterfaceImplementedBy(value!.GetType());
11241128
Assumes.NotNull(iface);
11251129
MethodInfo genericMethod = WriteJsonOpenGenericMethod.MakeGenericMethod(iface.GenericTypeArguments[0]);
11261130
try
@@ -1249,7 +1253,9 @@ public override void WriteJson(JsonWriter writer, Stream? value, JsonSerializer
12491253
}
12501254

12511255
[DebuggerDisplay("{" + nameof(DebuggerDisplay) + "}")]
1252-
private class RpcMarshalableConverter(Type interfaceType, JsonMessageFormatter jsonMessageFormatter, JsonRpcProxyOptions proxyOptions, JsonRpcTargetOptions targetOptions, RpcMarshalableAttribute rpcMarshalableAttribute) : JsonConverter
1256+
[RequiresDynamicCode(RuntimeReasons.CloseGenerics)]
1257+
[RequiresUnreferencedCode(RuntimeReasons.RefEmit)]
1258+
private class RpcMarshalableConverter([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents | DynamicallyAccessedMemberTypes.Interfaces)] Type interfaceType, JsonMessageFormatter jsonMessageFormatter, JsonRpcProxyOptions proxyOptions, JsonRpcTargetOptions targetOptions, RpcMarshalableAttribute rpcMarshalableAttribute) : JsonConverter
12531259
{
12541260
private string DebuggerDisplay => $"Converter for marshalable objects of type {interfaceType.FullName}";
12551261

@@ -1333,6 +1339,7 @@ public object Convert(object value, TypeCode typeCode)
13331339
public ulong ToUInt64(object value) => ((JToken)value).ToObject<ulong>(this.serializer);
13341340
}
13351341

1342+
[RequiresUnreferencedCode(RuntimeReasons.LoadType)]
13361343
private class ExceptionConverter : JsonConverter<Exception?>
13371344
{
13381345
/// <summary>

0 commit comments

Comments
 (0)