Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add JSON source-gen mode that emits serialization logic#53212

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
layomia merged 9 commits intodotnet:mainfromlayomia:GenSerializationLogic
May 27, 2021

Conversation

@layomia
Copy link
Contributor

@layomialayomia commentedMay 25, 2021
edited
Loading

Contributes to#51945.
Contributes to#52279.

Users kick off source generation by providing a partial, derived context class; and indicate serializable types and run-time options (optional):

namespaceSystem.Text.Json.SourceGeneration.Tests{[JsonSerializerOptions(DefaultIgnoreCondition=JsonIgnoreCondition.WhenWritingDefault,IgnoreReadOnlyProperties=true,IgnoreRuntimeCustomConverters=true,NamingPolicy=JsonKnownNamingPolicy.BuiltInCamelCase)][JsonSerializable(typeof(JsonMessage),GenerationMode=JsonSourceGenerationMode.Serialization)]internalpartialclassJsonContext:JsonSerializerContext{}publicclassJsonMessage{publicstringMessage{get;set;}publicintLength=>Message?.Length??0;// Read-only property}}
Generated code (click to view)
// <auto-generated/>namespaceSystem.Text.Json.SourceGeneration.Tests{[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Text.Json.SourceGeneration","6.0.0.0")]internalpartialclassJsonContext:global::System.Text.Json.Serialization.JsonSerializerContext{privatestaticglobal::System.Text.Json.JsonSerializerOptionss_defaultOptions{get;}=newglobal::System.Text.Json.JsonSerializerOptions(){DefaultIgnoreCondition=global::System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingDefault,IgnoreReadOnlyFields=false,IgnoreReadOnlyProperties=true,IncludeFields=false,WriteIndented=false,PropertyNamingPolicy=global::System.Text.Json.JsonNamingPolicy.CamelCase};privatestaticglobal::System.Text.Json.SourceGeneration.Tests.JsonContexts_defaultContext;publicstaticglobal::System.Text.Json.SourceGeneration.Tests.JsonContextDefault=>s_defaultContext??=newglobal::System.Text.Json.SourceGeneration.Tests.JsonContext(newglobal::System.Text.Json.JsonSerializerOptions(s_defaultOptions));privatestaticglobal::System.Text.Json.JsonEncodedTextmessagePropName=global::System.Text.Json.JsonEncodedText.Encode("message");privatestaticglobal::System.Text.Json.JsonEncodedTextlengthPropName=global::System.Text.Json.JsonEncodedText.Encode("length");publicJsonContext():base(null,s_defaultOptions){}publicJsonContext(global::System.Text.Json.JsonSerializerOptionsoptions):base(options,s_defaultOptions){}publicoverrideglobal::System.Text.Json.Serialization.Metadata.JsonTypeInfoGetTypeInfo(global::System.Typetype){if(type==typeof(global::System.Text.Json.SourceGeneration.Tests.JsonMessage)){returnthis.JsonMessage;}returnnull!;}privateglobal::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.Text.Json.SourceGeneration.Tests.JsonMessage>_JsonMessage;publicglobal::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.Text.Json.SourceGeneration.Tests.JsonMessage>JsonMessage{get{if(_JsonMessage==null){global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.Text.Json.SourceGeneration.Tests.JsonMessage>objectInfo=global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateObjectInfo<global::System.Text.Json.SourceGeneration.Tests.JsonMessage>();_JsonMessage=objectInfo;global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.InitializeObjectInfo(objectInfo,Options,createObjectFunc:static()=>newglobal::System.Text.Json.SourceGeneration.Tests.JsonMessage(),propInitFunc:null,default,serializeFunc:JsonMessageSerialize);}return_JsonMessage;}}privatestaticvoidJsonMessageSerialize(global::System.Text.Json.Utf8JsonWriterwriter,global::System.Text.Json.SourceGeneration.Tests.JsonMessagevalue){if(value==null){writer.WriteNullValue();return;}writer.WriteStartObject();if(value.Message!=null){writer.WriteString(messagePropName,value.Message);}writer.WriteEndObject();}}}

To use generated serialization code:

Interacting with generated func directly:

usingMemoryStreamms=new();Utf8JsonWriterwriter=new(ms);JsonContext.Default.JsonMessage.Serialize!(writer,newJsonMessage{Message="Hello, world!"});writer.Flush();

Interacting viaJsonSerializer:

JsonSerializer.Serialize(newJsonMessage{Message="Hello, world!"},JsonContext.Default.JsonMessage);

or

JsonSerializer.Serialize(newJsonMessage{Message="Hello, world!"},typeof(JsonMessage),JsonContext.Default);

FYI@pranavkm@SteveSandersonMS@terrajobst@ericstj@jkotas@stephentoub@davidfowl@SamMonoRT@CoffeeFlux

@ghost
Copy link

Tagging subscribers to this area:@eiriktsarpalis,@layomia
See info inarea-owners.md if you want to be subscribed.

Issue Details

Contributes to#51945.

Users kick off source generation by providing a partial, derived context class; and indicate serializable types and run-time options (optional):

namespaceSystem.Text.Json.SourceGeneration.Tests{[JsonSerializerOptions(DefaultIgnoreCondition=JsonIgnoreCondition.WhenWritingDefault,IgnoreReadOnlyProperties=true,IgnoreRuntimeCustomConverters=true,NamingPolicy=JsonKnownNamingPolicy.BuiltInCamelCase)][JsonSerializable(typeof(JsonMessage),GenerationMode=JsonSourceGenerationMode.Serialization)]internalpartialclassJsonContext:JsonSerializerContext{}publicclassJsonMessage{publicstringMessage{get;set;}publicintLength=>Message?.Length??0;// Read-only property}}
Generated code (click to view)
// <auto-generated/>namespaceSystem.Text.Json.SourceGeneration.Tests{[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Text.Json.SourceGeneration","6.0.0.0")]internalpartialclassJsonContext:global::System.Text.Json.Serialization.JsonSerializerContext{privatestaticglobal::System.Text.Json.JsonSerializerOptionss_defaultOptions{get;}=newglobal::System.Text.Json.JsonSerializerOptions(){DefaultIgnoreCondition=global::System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingDefault,IgnoreReadOnlyFields=false,IgnoreReadOnlyProperties=true,IncludeFields=false,WriteIndented=false,PropertyNamingPolicy=global::System.Text.Json.JsonNamingPolicy.CamelCase};privatestaticglobal::System.Text.Json.SourceGeneration.Tests.JsonContexts_defaultContext;publicstaticglobal::System.Text.Json.SourceGeneration.Tests.JsonContextDefault=>s_defaultContext??=newglobal::System.Text.Json.SourceGeneration.Tests.JsonContext(newglobal::System.Text.Json.JsonSerializerOptions(s_defaultOptions));privatestaticglobal::System.Text.Json.JsonEncodedTextmessagePropName=global::System.Text.Json.JsonEncodedText.Encode("message");privatestaticglobal::System.Text.Json.JsonEncodedTextlengthPropName=global::System.Text.Json.JsonEncodedText.Encode("length");publicJsonContext():base(null,s_defaultOptions){}publicJsonContext(global::System.Text.Json.JsonSerializerOptionsoptions):base(options,s_defaultOptions){}publicoverrideglobal::System.Text.Json.Serialization.Metadata.JsonTypeInfoGetTypeInfo(global::System.Typetype){if(type==typeof(global::System.Text.Json.SourceGeneration.Tests.JsonMessage)){returnthis.JsonMessage;}returnnull!;}privateglobal::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.Text.Json.SourceGeneration.Tests.JsonMessage>_JsonMessage;publicglobal::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.Text.Json.SourceGeneration.Tests.JsonMessage>JsonMessage{get{if(_JsonMessage==null){global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.Text.Json.SourceGeneration.Tests.JsonMessage>objectInfo=global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateObjectInfo<global::System.Text.Json.SourceGeneration.Tests.JsonMessage>();_JsonMessage=objectInfo;global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.InitializeObjectInfo(objectInfo,Options,createObjectFunc:static()=>newglobal::System.Text.Json.SourceGeneration.Tests.JsonMessage(),propInitFunc:null,default,serializeFunc:JsonMessageSerialize);}return_JsonMessage;}}privatestaticvoidJsonMessageSerialize(global::System.Text.Json.Utf8JsonWriterwriter,global::System.Text.Json.SourceGeneration.Tests.JsonMessagevalue){if(value==null){writer.WriteNullValue();return;}writer.WriteStartObject();if(value.Message!=null){writer.WriteString(messagePropName,value.Message);}writer.WriteEndObject();}}}

To use generated serialization code:

Interacting with generated func directly:

usingMemoryStreamms=new();Utf8JsonWriterwriter=new(ms);JsonContext.Default.JsonMessage.Serialize!(writer,newJsonMessage{Message="Hello, world!"});writer.Flush();

Interacting viaJsonSerializer:

JsonSerializer.Serialize(newJsonMessage{Message="Hello, world!"},JsonContext.Default.JsonMessage);

FYI@pranavkm@SteveSandersonMS@terrajobst@ericstj@jkotas@stephentoub@davidfowl@SamMonoRT@CoffeeFlux

Author:layomia
Assignees:layomia
Labels:

area-System.Text.Json

Milestone:6.0.0

@ghost
Copy link

Note regarding thenew-api-needs-documentation label:

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.

@ericstjericstj added the breaking-changeIssue or PR that represents a breaking API or functional change over a previous release. labelMay 25, 2021
@ghostghost added the needs-breaking-change-doc-createdBreaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet labelMay 25, 2021
using ReferencedAssembly;
using @JsonSerializable = System.Runtime.Serialization.ContractNamespaceAttribute;
using @JsonSerializable = System.Runtime.Serialization.CollectionDataContractAttribute;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Why use S.R.S.CollectionDataContractAttribute here?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I changed to this because, likeJsonSerializableAttribute, it is applied toclasses.

Copy link
ContributorAuthor

@layomialayomiaMay 26, 2021
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This test is modeling type aliasing. In this case, we have two attributes switching names. The test makes sure that our check for[JsonSerializable(Type)] guards against such tricks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I see. A comment here about that would be useful. Thanks

layomia reacted with thumbs up emoji
@layomialayomiaforce-pushed theGenSerializationLogic branch from330722b tof855af8CompareMay 26, 2021 23:45
Copy link
Member

@ericstjericstj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Lgtm. Let’s get this in so we can get a preview s out. Any additional feedback can be addressed in follow up prs.

@ericstj
Copy link
Member

All these PGO failures were caused by#53301,@AndyAyersMS and@BruceForstall have helped get this fixed, but we can't get rid of the badges without pushing new changes / resetting CI. Since we know this PR didn't introduce the PGO failures we can safely ignore those.

layomia reacted with thumbs up emoji

@layomia
Copy link
ContributorAuthor

TheBuild Browser wasm Release AllSubsets_Mono failure is unrelated and might be fixed by#53280. cc@ericstj

@layomialayomia merged commit6e5f722 intodotnet:mainMay 27, 2021
@layomia
Copy link
ContributorAuthor

/backport to release/6.0-preview5

@github-actions
Copy link
Contributor

Started backporting to release/6.0-preview5:https://github.com/dotnet/runtime/actions/runs/881152471

@layomia
Copy link
ContributorAuthor

These breaking changes have already hit customers & the APIs have changed further since then -dotnet/docs#26200.

@layomialayomia removed the needs-breaking-change-doc-createdBreaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet labelNov 2, 2021
Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.

Reviewers

@jkotasjkotasjkotas left review comments

@eerhardteerhardteerhardt left review comments

@ericstjericstjericstj approved these changes

@eiriktsarpaliseiriktsarpalisAwaiting requested review from eiriktsarpalis

@jozkeejozkeeAwaiting requested review from jozkee

+1 more reviewer

@steveharterstevehartersteveharter left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

@layomialayomia

Labels

area-System.Text.Jsonbreaking-changeIssue or PR that represents a breaking API or functional change over a previous release.new-api-needs-documentation

Projects

None yet

Milestone

6.0.0

Development

Successfully merging this pull request may close these issues.

6 participants

@layomia@Tornhoof@ericstj@jkotas@steveharter@eerhardt

[8]ページ先頭

©2009-2025 Movatter.jp