Skip to content
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

BinaryData + JSON source gen produces compiler warnings #81702

Closed
krwq opened this issue Feb 6, 2023 · 8 comments · Fixed by #89454
Closed

BinaryData + JSON source gen produces compiler warnings #81702

krwq opened this issue Feb 6, 2023 · 8 comments · Fixed by #89454
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-System.Memory blocking Marks issues that we want to fast track in order to unblock other important work
Milestone

Comments

@krwq
Copy link
Member

krwq commented Feb 6, 2023

EDIT by @eiriktsarpalis to reflect more recent error modes

In #73448 we've added internal converter for BinaryData but that's not working with JSON source-gen.

Repro

using System.Text.Json.Serialization;

[JsonSerializable(typeof(BinaryData))]
partial class MyContext : JsonSerializerContext { }

Expected behavior:

Compiles and works when you serialize/deserialize

Actual

warning SYSLIB1041: The 'JsonConverterAttribute' type 'System.BinaryDataConverter' specified on member 'System.BinaryData' is not a converter type or does not contain an accessible parameterless constructor.

API Proposal

We should make the constructor of the already included custom converter public:

namespace System;

[JsonConverter(typeof(BinaryDataConverter))]
public partial class BinaryData { }

-internal sealed class BinaryDataConverter : JsonConverter<BinaryData> { }
+namespace System.Text.Json.Serialization;
+
+public sealed class BinaryDataConverter : JsonConverter<BinaryData> { }
@krwq krwq added this to the 8.0.0 milestone Feb 6, 2023
@ghost
Copy link

ghost commented Feb 6, 2023

Tagging subscribers to this area: @dotnet/area-system-memory
See info in area-owners.md if you want to be subscribed.

Issue Details

In #73448 we've added internal converter for BinaryData but that's not working with JSON source-gen.

Repro

using System.Text.Json.Serialization;

[JsonSerializable(typeof(BinaryData))]
partial class MyContext : JsonSerializerContext { }

Expected behavior:

Works

Actual

Error    CS0122    'BinaryDataConverter' is inaccessible due to its protection level

Code produced by source-gen (7.0):

// <auto-generated/>

#nullable enable annotations
#nullable disable warnings

// Suppress warnings about [Obsolete] member usage in generated code.
#pragma warning disable CS0618
    partial class MyContext
    {
        private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData>? _BinaryData;
        /// <summary>
        /// Defines the source generated JSON serialization contract metadata for a given type.
        /// </summary>
        public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData> BinaryData
        {
            get => _BinaryData ??= Create_BinaryData(Options, makeReadOnly: true);
        }
        
        private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData> Create_BinaryData(global::System.Text.Json.JsonSerializerOptions options, bool makeReadOnly)
        {
            global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData>? jsonTypeInfo = null;
            global::System.Text.Json.Serialization.JsonConverter? customConverter;
            if (options.Converters.Count > 0 && (customConverter = GetRuntimeProvidedCustomConverter(options, typeof(global::System.BinaryData))) != null)
            {
                jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo<global::System.BinaryData>(options, customConverter);
            }
            else
            {
                global::System.Text.Json.Serialization.JsonConverter converter = new global::System.BinaryDataConverter();
                        global::System.Type typeToConvert = typeof(global::System.BinaryData);
                        if (!converter.CanConvert(typeToConvert))
                        {
                            throw new global::System.InvalidOperationException(string.Format("The converter '{0}' is not compatible with the type '{1}'.", converter.GetType(), typeToConvert));
                        }
                        jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo<global::System.BinaryData> (options, converter); 
            }
        
            if (makeReadOnly)
            {
                jsonTypeInfo.MakeReadOnly();
            }
        
            return jsonTypeInfo;
        }
        
    }
Author: krwq
Assignees: -
Labels:

area-System.Memory

Milestone: 8.0.0

@ghost
Copy link

ghost commented May 31, 2023

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

Issue Details

In #73448 we've added internal converter for BinaryData but that's not working with JSON source-gen.

Repro

using System.Text.Json.Serialization;

[JsonSerializable(typeof(BinaryData))]
partial class MyContext : JsonSerializerContext { }

Expected behavior:

Compiles and works when you serialize/deserialize

Actual

Error    CS0122    'BinaryDataConverter' is inaccessible due to its protection level

Code produced by source-gen (7.0):

// <auto-generated/>

#nullable enable annotations
#nullable disable warnings

// Suppress warnings about [Obsolete] member usage in generated code.
#pragma warning disable CS0618
    partial class MyContext
    {
        private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData>? _BinaryData;
        /// <summary>
        /// Defines the source generated JSON serialization contract metadata for a given type.
        /// </summary>
        public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData> BinaryData
        {
            get => _BinaryData ??= Create_BinaryData(Options, makeReadOnly: true);
        }
        
        private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData> Create_BinaryData(global::System.Text.Json.JsonSerializerOptions options, bool makeReadOnly)
        {
            global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData>? jsonTypeInfo = null;
            global::System.Text.Json.Serialization.JsonConverter? customConverter;
            if (options.Converters.Count > 0 && (customConverter = GetRuntimeProvidedCustomConverter(options, typeof(global::System.BinaryData))) != null)
            {
                jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo<global::System.BinaryData>(options, customConverter);
            }
            else
            {
                global::System.Text.Json.Serialization.JsonConverter converter = new global::System.BinaryDataConverter();
                        global::System.Type typeToConvert = typeof(global::System.BinaryData);
                        if (!converter.CanConvert(typeToConvert))
                        {
                            throw new global::System.InvalidOperationException(string.Format("The converter '{0}' is not compatible with the type '{1}'.", converter.GetType(), typeToConvert));
                        }
                        jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo<global::System.BinaryData> (options, converter); 
            }
        
            if (makeReadOnly)
            {
                jsonTypeInfo.MakeReadOnly();
            }
        
            return jsonTypeInfo;
        }
        
    }
Author: krwq
Assignees: eiriktsarpalis
Labels:

area-System.Text.Json, source-generator

Milestone: 8.0.0

@eiriktsarpalis
Copy link
Member

In order to have the type supported in source gen the custom converter needs to be made public.

@eiriktsarpalis eiriktsarpalis added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Jun 5, 2023
@eiriktsarpalis eiriktsarpalis modified the milestones: 8.0.0, Future Jun 5, 2023
@layomia
Copy link
Contributor

layomia commented Jun 5, 2023

@eiriktsarpalis with #87136 do we stop generating the converter logic?

@eiriktsarpalis
Copy link
Member

That's right. It will no longer fail to compile but the custom converter won't be picked up.

@eiriktsarpalis
Copy link
Member

#87140 tracks adding a SG diagnostic for this particular failure.

@ghost
Copy link

ghost commented Jun 5, 2023

Tagging subscribers to this area: @dotnet/area-system-memory
See info in area-owners.md if you want to be subscribed.

Issue Details

In #73448 we've added internal converter for BinaryData but that's not working with JSON source-gen.

Repro

using System.Text.Json.Serialization;

[JsonSerializable(typeof(BinaryData))]
partial class MyContext : JsonSerializerContext { }

Expected behavior:

Compiles and works when you serialize/deserialize

Actual

Error    CS0122    'BinaryDataConverter' is inaccessible due to its protection level

Code produced by source-gen (7.0):

// <auto-generated/>

#nullable enable annotations
#nullable disable warnings

// Suppress warnings about [Obsolete] member usage in generated code.
#pragma warning disable CS0618
    partial class MyContext
    {
        private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData>? _BinaryData;
        /// <summary>
        /// Defines the source generated JSON serialization contract metadata for a given type.
        /// </summary>
        public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData> BinaryData
        {
            get => _BinaryData ??= Create_BinaryData(Options, makeReadOnly: true);
        }
        
        private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData> Create_BinaryData(global::System.Text.Json.JsonSerializerOptions options, bool makeReadOnly)
        {
            global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.BinaryData>? jsonTypeInfo = null;
            global::System.Text.Json.Serialization.JsonConverter? customConverter;
            if (options.Converters.Count > 0 && (customConverter = GetRuntimeProvidedCustomConverter(options, typeof(global::System.BinaryData))) != null)
            {
                jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo<global::System.BinaryData>(options, customConverter);
            }
            else
            {
                global::System.Text.Json.Serialization.JsonConverter converter = new global::System.BinaryDataConverter();
                        global::System.Type typeToConvert = typeof(global::System.BinaryData);
                        if (!converter.CanConvert(typeToConvert))
                        {
                            throw new global::System.InvalidOperationException(string.Format("The converter '{0}' is not compatible with the type '{1}'.", converter.GetType(), typeToConvert));
                        }
                        jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo<global::System.BinaryData> (options, converter); 
            }
        
            if (makeReadOnly)
            {
                jsonTypeInfo.MakeReadOnly();
            }
        
            return jsonTypeInfo;
        }
        
    }
Author: krwq
Assignees: -
Labels:

api-suggestion, area-System.Memory

Milestone: Future

@eiriktsarpalis eiriktsarpalis changed the title BinaryData + JSON source gen produces compile errors BinaryData + JSON source gen produces compiler warnings Jul 24, 2023
@eiriktsarpalis eiriktsarpalis modified the milestones: Future, 8.0.0 Jul 24, 2023
@eiriktsarpalis eiriktsarpalis added api-ready-for-review API is ready for review, it is NOT ready for implementation and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Jul 24, 2023
@eiriktsarpalis eiriktsarpalis self-assigned this Jul 24, 2023
@eiriktsarpalis eiriktsarpalis added blocking-release blocking Marks issues that we want to fast track in order to unblock other important work and removed blocking-release labels Jul 24, 2023
@eiriktsarpalis eiriktsarpalis modified the milestones: Future, 8.0.0 Jul 24, 2023
@terrajobst
Copy link
Member

terrajobst commented Jul 25, 2023

Video

  • We should add Json somewhere in the name. It felt right to put before the converter.
namespace System.Text.Json.Serialization;

public sealed class BinaryDataJsonConverter : JsonConverter<BinaryData>
{
    // Overrides omitted
}

@terrajobst terrajobst added the api-approved API was approved in API review, it can be implemented label Jul 25, 2023
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 25, 2023
@terrajobst terrajobst removed the api-ready-for-review API is ready for review, it is NOT ready for implementation label Jul 25, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jul 26, 2023
@dotnet dotnet locked as resolved and limited conversation to collaborators Aug 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Memory blocking Marks issues that we want to fast track in order to unblock other important work
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants