-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Annotating System.Text.Json library for aot form factor #68464
Conversation
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsThe annotation falls into two categories and incorporates fb from the old PR, #67582.
New PR instead of continuing from previous one, #67582, since there has been significant external changes that impact this library, including getting #67368 approved. The previous PR feedback is reflected in this change, specifically,
|
...ies/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs
Outdated
Show resolved
Hide resolved
...src/System/Text/Json/Serialization/Converters/Collection/IAsyncEnumerableConverterFactory.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs
Outdated
Show resolved
Hide resolved
...ries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like I didn't submit these comments yesterday. (Sorry)
src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs
Outdated
Show resolved
Hide resolved
...System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverterFactory.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs
Outdated
Show resolved
Hide resolved
...ries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs
Outdated
Show resolved
Hide resolved
...es/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptionsUpdateHandler.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs
Outdated
Show resolved
Hide resolved
....Json/src/System/Text/Json/Serialization/Converters/Value/UnsupportedTypeConverterFactory.cs
Outdated
Show resolved
Hide resolved
...es/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionJsonTypeInfoOfT.cs
Outdated
Show resolved
Hide resolved
How are these annotations being checked? Is the analyzer turned on during the build? If so, can you point me to where it is turned on? |
public JsonStringEnumConverter() { } | ||
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is rather unfortunate that we can't support converting enums to and from strings without requiring dynamic code. It feels like we should be able to make something work here for NativeAOT.
I don't think you need to solve this in this PR, so maybe we can open an issue for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is rather unfortunate that we can't support converting enums to and from strings without requiring dynamic code.
Runtime allows you to convert enums to and from strings with NativeAOT. The problem is that the EnumConverter implementation creates new generic types dynamically: typeof(EnumConverter<>).MakeGenericType
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I'm thinking (in a separate PR) we add a switch to JsonStringEnumConverter on RuntimeFeature.IsDynamicCodeSupported
, and fallback to some other implementation when dynamic code isn't supported. Then we can remove this attribute and support this API in NativeAOT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the JsonStringEnumConverter
used with serialization source generators?
If yes, I think there should be a static path that is both fast and that does not require dynamical code generation. For example, can EnumConverter<T>
be public and source generators changed to use it?
If not, I do not think we need to bother with making it AOT friendly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eiriktsarpalis @layomia @krwq - can one of you answer this? Can the JsonStringEnumConverter
be used outside of the reflection-based serialization? i.e. with source generation.
src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonValue.cs
Outdated
Show resolved
Hide resolved
...em.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverterFactory.cs
Outdated
Show resolved
Hide resolved
runtime-dev-innerloop build is failing with |
Its opt-in right now with /p:EnableAOTAnalyzer=true. For native AOT apps, its automatically turned on with this SDK PR. The ILC compiler should also separately give similar warnings for the IL. |
Should we be turning that property on for this library with this change? There are new features and bug fixes happening in this library, and I think we would want to ensure the library's annotations stay up to date. |
Yes please, we will definitely be refactoring some of the code being touched by these changes. We should try to avoid inadvertently breaking AOT annotations in the future. |
...ries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs
Outdated
Show resolved
Hide resolved
...em.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverterFactory.cs
Outdated
Show resolved
Hide resolved
....Json/src/System/Text/Json/Serialization/Converters/Value/UnsupportedTypeConverterFactory.cs
Outdated
Show resolved
Hide resolved
...Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.cs
Outdated
Show resolved
Hide resolved
...System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs
Outdated
Show resolved
Hide resolved
[UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", Justification = "The factory constructors are only invoked in the context of reflection serialization code paths " + | ||
"and are marked RequiresDynamicCode")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this marked with RequiresDynamicCode
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This API is a gateway to a much larger dependency graph. I need to understand the potential impact on Json source generated paths better to correctly annotate this and need help from @eiriktsarpalis @layomia @krwq first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is somewhat concerning. If this means the source generation path might not work in NativeAot, we will need to understand it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this suppression be replaced by proper annotations instead?
For example, I see the following callchain:
[RequiresDynamicCode] public GetConverter
->
GetConverterInternal
(not annotated)
->
GetConverterFromType
(not annotated)
->
[UnconditionalSuppressMessage] GetConverterFromAttribute
Should GetConverterInternal
and GetConverterFromType
be annotated as RequiresDynamicCode
on this call-chain? (And similar to other call-chains.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are 2 concerns in the call graph that I left open to get FB;
- SourceGenJsonTypeInfo has 2 nodes in the path; ObjectDefaultConverter and an assert. Is it safe to suppress these calls?
- JsonMetadataServices: Has a call to ObjectCoverter that is used by GetDefaultSimpleConverters. Not sure what to do here., via
WriteAsPropertyNameCore
->GetConverterInternal
->GetConverterFromType
->GetConverterFromAttribute
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened #68878 to track the status since there needs to be converter changes that should be done by domain experts in this space.
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs
Outdated
Show resolved
Hide resolved
c857681
to
3eff9c3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this work, @LakshanF. This looks good to me. Hopefully that one remaining suppression won't be too much work to solve in a follow up.
The annotation falls into two categories and incorporates fb from the old PR, #67582.
DynamicMethod
calls: AllDynamicMethod
calls are behind the runtime feature switch and propagated up to the switch method and suppressedMakeGenericXXX
in the trimmer but by usingRequiresDynamicCode
New PR instead of continuing from previous one, #67582, since there has been significant external changes that impact this library, including getting #67368 approved. The previous PR feedback is reflected in this change, specifically,
IL3051
suppression fromReflectionEmitMemberAccessor
andReflectionEmitCachingMemberAccessor
as suggested.