Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0e62773
Enable NativeAOT flag and warnings
AArnott Oct 11, 2024
8b84353
Add some attributes
AArnott Oct 14, 2024
4934c03
More attributes
AArnott Apr 1, 2025
58473e8
More attributes
AArnott Apr 1, 2025
86617c6
The rest of the attributes that I know how to place
AArnott Apr 1, 2025
4641412
Solve more warnings
AArnott Apr 2, 2025
6c880d8
Get StreamJsonRpc warning free
AArnott Apr 2, 2025
8e22530
Suppress a few dotnet publish warnings
AArnott Apr 5, 2025
05d94b3
wip
AArnott Apr 22, 2025
4cbcd76
Define a NativeAOT safe path for StreamJsonRpc
AArnott Jun 8, 2025
aff36d6
Suppress 2 warnings
AArnott Jun 13, 2025
e40a568
Fix test failures
AArnott Jun 13, 2025
3bb8f20
Cut ProxyGeneration out if dynamic code isn't supported
eerhardt Jun 13, 2025
73b94d3
Merge pull request #1202 from eerhardt:ThrowOnNoDynamicCode
AArnott Jun 13, 2025
959c7ba
Refactor code and annotations to fix all warnings in NativeAOTCompati…
eerhardt Jun 18, 2025
b889dd9
Refactor TrackerHelper to not need DynamicallyAccessedMembers attribu…
eerhardt Jun 18, 2025
a274eeb
Respond to PR feedback
eerhardt Jun 18, 2025
e89f197
Refactor code and annotations to fix all warnings in NativeAOTCompati…
AArnott Jun 19, 2025
adbc89c
Merge remote-tracking branch 'origin/main' into NativeAOT
AArnott Jun 19, 2025
252189f
Fix symbol archival to recognize NativeAOTCompatibility as a test
AArnott Jun 19, 2025
fbc2174
Minor PR feedback
eerhardt Jun 19, 2025
c0926af
Minor formatting change
eerhardt Jun 19, 2025
3f58494
Merge pull request #1210 from eerhardt/NativeAOT_eerhardtFollowup
AArnott Jun 19, 2025
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
7 changes: 7 additions & 0 deletions StreamJsonRpc.sln
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{F446B894-5
test\Directory.Build.targets = test\Directory.Build.targets
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeAOTCompatibility.Test", "test\NativeAOTCompatibility.Test\NativeAOTCompatibility.Test.csproj", "{1837EED6-4236-09AA-AEAA-0B8F5C35813E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -60,6 +62,10 @@ Global
{5936CF62-A59D-4E5C-9EE4-5E8BAFA9F215}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5936CF62-A59D-4E5C-9EE4-5E8BAFA9F215}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5936CF62-A59D-4E5C-9EE4-5E8BAFA9F215}.Release|Any CPU.Build.0 = Release|Any CPU
{1837EED6-4236-09AA-AEAA-0B8F5C35813E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1837EED6-4236-09AA-AEAA-0B8F5C35813E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1837EED6-4236-09AA-AEAA-0B8F5C35813E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1837EED6-4236-09AA-AEAA-0B8F5C35813E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -69,6 +75,7 @@ Global
{8BF355B2-E3B0-4615-BFC1-7563EADC4F8B} = {F446B894-56AA-4653-ADC0-5FFC911C9C13}
{CEF0F77F-19EB-4C76-A050-854984BB0364} = {F446B894-56AA-4653-ADC0-5FFC911C9C13}
{5936CF62-A59D-4E5C-9EE4-5E8BAFA9F215} = {F446B894-56AA-4653-ADC0-5FFC911C9C13}
{1837EED6-4236-09AA-AEAA-0B8F5C35813E} = {F446B894-56AA-4653-ADC0-5FFC911C9C13}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4946F7E7-0619-414B-BE56-DDF0261CA8A9}
Expand Down
3 changes: 3 additions & 0 deletions azure-pipelines/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ jobs:
parameters:
Is1ESPT: ${{ parameters.Is1ESPT }}
RunTests: ${{ parameters.RunTests }}
osRID: win
IsOptProf: ${{ parameters.IsOptProf }}

- ${{ if and(parameters.EnableDotNetFormatCheck, not(parameters.EnableLinuxBuild)) }}:
Expand Down Expand Up @@ -243,6 +244,7 @@ jobs:
parameters:
Is1ESPT: ${{ parameters.Is1ESPT }}
RunTests: ${{ parameters.RunTests }}
osRID: linux
- ${{ if parameters.EnableDotNetFormatCheck }}:
- script: dotnet format --verify-no-changes
displayName: 💅 Verify formatted code
Expand Down Expand Up @@ -277,6 +279,7 @@ jobs:
parameters:
Is1ESPT: ${{ parameters.Is1ESPT }}
RunTests: ${{ parameters.RunTests }}
osRID: osx

- job: WrapUp
dependsOn:
Expand Down
6 changes: 6 additions & 0 deletions azure-pipelines/dotnet.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
parameters:
- name: RunTests
- name: osRID
type: string
- name: IsOptProf
type: boolean
default: false
Expand Down Expand Up @@ -40,6 +42,10 @@ steps:
- script: dotnet pack src\VSInsertionMetadata -c $(BuildConfiguration) -warnaserror /bl:"$(Build.ArtifactStagingDirectory)/build_logs/VSInsertion-Pack.binlog"
displayName: 🔧 dotnet pack VSInsertionMetadata

- script: dotnet publish -r ${{ parameters.osRID }}-x64 -warnaserror
displayName: 🧪 NativeAOT test
workingDirectory: test/NativeAOTCompatibility.Test

- powershell: tools/variables/_define.ps1
failOnStderr: true
displayName: ⚙ Update pipeline variables based on build outputs
Expand Down
3 changes: 3 additions & 0 deletions src/StreamJsonRpc/HeaderDelimitedMessageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Buffers;
using System.Buffers.Text;
using System.Diagnostics.CodeAnalysis;
using System.IO.Pipelines;
using System.Net.Http.Headers;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -97,6 +98,7 @@ public HeaderDelimitedMessageHandler(Stream duplexStream, IJsonRpcMessageFormatt
/// Initializes a new instance of the <see cref="HeaderDelimitedMessageHandler"/> class.
/// </summary>
/// <param name="duplexStream">The stream to use for transmitting and receiving messages.</param>
[RequiresDynamicCode(RuntimeReasons.Formatters), RequiresUnreferencedCode(RuntimeReasons.Formatters)]
public HeaderDelimitedMessageHandler(Stream duplexStream)
: this(duplexStream, duplexStream)
{
Expand All @@ -107,6 +109,7 @@ public HeaderDelimitedMessageHandler(Stream duplexStream)
/// </summary>
/// <param name="sendingStream">The stream to use for transmitting messages.</param>
/// <param name="receivingStream">The stream to use for receiving messages.</param>
[RequiresDynamicCode(RuntimeReasons.Formatters), RequiresUnreferencedCode(RuntimeReasons.Formatters)]
public HeaderDelimitedMessageHandler(Stream? sendingStream, Stream? receivingStream)
: this(sendingStream, receivingStream, new JsonMessageFormatter())
{
Expand Down
13 changes: 10 additions & 3 deletions src/StreamJsonRpc/JsonMessageFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace StreamJsonRpc;
/// <remarks>
/// Each instance of this class may only be used with a single <see cref="JsonRpc" /> instance.
/// </remarks>
[RequiresDynamicCode(RuntimeReasons.Formatters), RequiresUnreferencedCode(RuntimeReasons.Formatters)]
public class JsonMessageFormatter : FormatterBase, IJsonRpcAsyncMessageTextFormatter, IJsonRpcMessageFactory
{
/// <summary>
Expand Down Expand Up @@ -1009,6 +1010,7 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer
/// <summary>
/// Converts a progress token to an <see cref="IProgress{T}"/>.
/// </summary>
[RequiresDynamicCode(RuntimeReasons.CloseGenerics)]
private class JsonProgressServerConverter : JsonConverter
{
private readonly JsonMessageFormatter formatter;
Expand Down Expand Up @@ -1042,6 +1044,7 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer
/// <summary>
/// Converts an enumeration token to an <see cref="IAsyncEnumerable{T}"/>.
/// </summary>
[RequiresDynamicCode(RuntimeReasons.CloseGenerics)]
private class AsyncEnumerableConsumerConverter : JsonConverter
{
private static readonly MethodInfo ReadJsonOpenGenericMethod = typeof(AsyncEnumerableConsumerConverter).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic).Single(m => m.Name == nameof(ReadJson) && m.IsGenericMethod);
Expand All @@ -1062,7 +1065,7 @@ internal AsyncEnumerableConsumerConverter(JsonMessageFormatter jsonMessageFormat
return null;
}

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

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

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

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

[RequiresUnreferencedCode(RuntimeReasons.LoadType)]
private class ExceptionConverter : JsonConverter<Exception?>
{
/// <summary>
Expand Down
Loading