Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Prev Previous commit
Next Next commit
Rename fast-path func name and add src-gen/JsonNode interop support
  • Loading branch information
layomia committed Sep 15, 2021
commit 77efb55f7f399c28628fcb192248f99a78c46732
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ private sealed partial class Emitter
private const string OptionsInstanceVariableName = "Options";
private const string PropInitMethodNameSuffix = "PropInit";
private const string RuntimeCustomConverterFetchingMethodName = "GetRuntimeProvidedCustomConverter";
private const string SerializeMethodNameSuffix = "Serialize";
private const string SerializeHandlerPropName = "SerializeHandler";
private const string ValueVarName = "value";
private const string WriterVarName = "writer";
Expand Down Expand Up @@ -436,7 +435,7 @@ private string GenerateForCollection(TypeGenerationSpec typeGenerationSpec)
? GenerateFastPathFuncForEnumerable(typeGenerationSpec)
: GenerateFastPathFuncForDictionary(typeGenerationSpec);

serializeHandlerValue = $"{typeGenerationSpec.FastPathSerializeMethodName}";
serializeHandlerValue = $"{typeGenerationSpec.TypeInfoPropertyName}{SerializeHandlerPropName}";
}

CollectionType collectionType = typeGenerationSpec.CollectionType;
Expand Down Expand Up @@ -571,7 +570,7 @@ private string GenerateFastPathFuncForEnumerable(TypeGenerationSpec typeGenerati
{WriterVarName}.WriteEndArray();";

return GenerateFastPathFuncForType(
typeGenerationSpec.FastPathSerializeMethodName,
$"{typeGenerationSpec.TypeInfoPropertyName}{SerializeHandlerPropName}",
typeGenerationSpec.TypeRef,
serializationLogic,
typeGenerationSpec.CanBeNull);
Expand Down Expand Up @@ -615,7 +614,7 @@ private string GenerateFastPathFuncForDictionary(TypeGenerationSpec typeGenerati
{WriterVarName}.WriteEndObject();";

return GenerateFastPathFuncForType(
typeGenerationSpec.FastPathSerializeMethodName,
$"{typeGenerationSpec.TypeInfoPropertyName}{SerializeHandlerPropName}",
typeGenerationSpec.TypeRef,
serializationLogic,
typeGenerationSpec.CanBeNull);
Expand Down Expand Up @@ -657,7 +656,7 @@ private string GenerateForObject(TypeGenerationSpec typeMetadata)
if (typeMetadata.GenerateSerializationLogic)
{
serializeFuncSource = GenerateFastPathFuncForObject(typeMetadata);
serializeMethodName = $"{typeFriendlyName}{SerializeMethodNameSuffix}";
serializeMethodName = $"{typeFriendlyName}{SerializeHandlerPropName}";
}

const string ObjectInfoVarName = "objectInfo";
Expand Down Expand Up @@ -835,7 +834,7 @@ private string GenerateFastPathFuncForObject(TypeGenerationSpec typeGenSpec)
{
JsonSourceGenerationOptionsAttribute options = _currentContext.GenerationOptions;
string typeRef = typeGenSpec.TypeRef;
string serializeMethodName = $"{typeGenSpec.TypeInfoPropertyName}{SerializeMethodNameSuffix}";
string serializeMethodName = $"{typeGenSpec.TypeInfoPropertyName}{SerializeHandlerPropName}";

if (!typeGenSpec.TryFilterSerializableProps(
options,
Expand Down Expand Up @@ -1067,7 +1066,7 @@ private string GetSerializeLogicForNonPrimitiveType(string typeInfoPropertyName,

if (serializationLogicGenerated)
{
return $"{typeInfoPropertyName}{SerializeMethodNameSuffix}({WriterVarName}, {valueToWrite});";
return $"{typeInfoPropertyName}{SerializeHandlerPropName}({WriterVarName}, {valueToWrite});";
}

return $"{JsonSerializerTypeRef}.Serialize({WriterVarName}, {valueToWrite}, {typeInfoRef});";
Expand Down
12 changes: 12 additions & 0 deletions src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ private sealed class Parser
private const string SystemTextJsonNamespace = "System.Text.Json";
private const string JsonConverterAttributeFullName = "System.Text.Json.Serialization.JsonConverterAttribute";
private const string JsonConverterFactoryFullName = "System.Text.Json.Serialization.JsonConverterFactory";
private const string JsonArrayFullName = "System.Text.Json.Nodes.JsonArray";
private const string JsonElementFullName = "System.Text.Json.JsonElement";
private const string JsonExtensionDataAttributeFullName = "System.Text.Json.Serialization.JsonExtensionDataAttribute";
private const string JsonNodeFullName = "System.Text.Json.Nodes.JsonNode";
private const string JsonObjectFullName = "System.Text.Json.Nodes.JsonObject";
private const string JsonValueFullName = "System.Text.Json.Nodes.JsonValue";
private const string JsonIgnoreAttributeFullName = "System.Text.Json.Serialization.JsonIgnoreAttribute";
private const string JsonIgnoreConditionFullName = "System.Text.Json.Serialization.JsonIgnoreCondition";
private const string JsonIncludeAttributeFullName = "System.Text.Json.Serialization.JsonIncludeAttribute";
Expand Down Expand Up @@ -80,8 +83,11 @@ private sealed class Parser
private readonly Type? _guidType;
private readonly Type? _uriType;
private readonly Type? _versionType;
private readonly Type? _jsonArrayType;
private readonly Type? _jsonElementType;
private readonly Type? _jsonNodeType;
private readonly Type? _jsonObjectType;
private readonly Type? _jsonValueType;

// Unsupported types
private readonly Type _typeType;
Expand Down Expand Up @@ -193,8 +199,11 @@ public Parser(Compilation compilation, in JsonSourceGenerationContext sourceGene
_guidType = _metadataLoadContext.Resolve(typeof(Guid));
_uriType = _metadataLoadContext.Resolve(typeof(Uri));
_versionType = _metadataLoadContext.Resolve(typeof(Version));
_jsonArrayType = _metadataLoadContext.Resolve(JsonArrayFullName);
_jsonElementType = _metadataLoadContext.Resolve(JsonElementFullName);
_jsonNodeType = _metadataLoadContext.Resolve(JsonNodeFullName);
_jsonObjectType = _metadataLoadContext.Resolve(JsonObjectFullName);
_jsonValueType = _metadataLoadContext.Resolve(JsonValueFullName);

// Unsupported types.
_typeType = _metadataLoadContext.Resolve(typeof(Type));
Expand Down Expand Up @@ -1446,8 +1455,11 @@ private void PopulateKnownTypes()
AddTypeIfNotNull(_knownTypes, _guidType);
AddTypeIfNotNull(_knownTypes, _uriType);
AddTypeIfNotNull(_knownTypes, _versionType);
AddTypeIfNotNull(_knownTypes, _jsonArrayType);
AddTypeIfNotNull(_knownTypes, _jsonElementType);
AddTypeIfNotNull(_knownTypes, _jsonNodeType);
AddTypeIfNotNull(_knownTypes, _jsonObjectType);
AddTypeIfNotNull(_knownTypes, _jsonValueType);

_knownUnsupportedTypes.Add(_typeType);
_knownUnsupportedTypes.Add(_serializationInfoType);
Expand Down
9 changes: 0 additions & 9 deletions src/libraries/System.Text.Json/gen/TypeGenerationSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,6 @@ internal class TypeGenerationSpec
public bool HasPropertyFactoryConverters { get; private set; }
public bool HasTypeFactoryConverter { get; private set; }

public string FastPathSerializeMethodName
{
get
{
Debug.Assert(GenerateSerializationLogic);
return $"{TypeInfoPropertyName}Serialize";
}
}

public string? ImmutableCollectionBuilderName
{
get
Expand Down
5 changes: 4 additions & 1 deletion src/libraries/System.Text.Json/ref/System.Text.Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -971,8 +971,11 @@ public static partial class JsonMetadataServices
public static System.Text.Json.Serialization.JsonConverter<short> Int16Converter { get { throw null; } }
public static System.Text.Json.Serialization.JsonConverter<int> Int32Converter { get { throw null; } }
public static System.Text.Json.Serialization.JsonConverter<long> Int64Converter { get { throw null; } }
public static System.Text.Json.Serialization.JsonConverter<System.Text.Json.Nodes.JsonArray> JsonArrayConverter { get { throw null; } }
public static System.Text.Json.Serialization.JsonConverter<System.Text.Json.JsonElement> JsonElementConverter { get { throw null; } }
public static System.Text.Json.Serialization.JsonConverter<System.Text.Json.Nodes.JsonNode> JsonNodeConverter { get { throw null; } }
public static System.Text.Json.Serialization.JsonConverter<System.Text.Json.Nodes.JsonObject> JsonObjectConverter { get { throw null; } }
public static System.Text.Json.Serialization.JsonConverter<System.Text.Json.Nodes.JsonValue> JsonValueConverter { get { throw null; } }
public static System.Text.Json.Serialization.JsonConverter<object> ObjectConverter { get { throw null; } }
[System.CLSCompliantAttribute(false)]
public static System.Text.Json.Serialization.JsonConverter<sbyte> SByteConverter { get { throw null; } }
Expand Down Expand Up @@ -1062,6 +1065,6 @@ internal JsonTypeInfo() { }
public abstract partial class JsonTypeInfo<T> : System.Text.Json.Serialization.Metadata.JsonTypeInfo
{
internal JsonTypeInfo() { }
public System.Action<System.Text.Json.Utf8JsonWriter, T>? Serialize { get { throw null; } }
public System.Action<System.Text.Json.Utf8JsonWriter, T>? SerializeHandler { get { throw null; } }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace System.Text.Json.Serialization.Converters
{
/// <summary>
/// Provides a mechanism to invoke "fast-path" serialization logic via
/// <see cref="JsonTypeInfo{T}.Serialize"/>. This type holds an optional
/// <see cref="JsonTypeInfo{T}.SerializeHandler"/>. This type holds an optional
/// reference to an actual <see cref="JsonConverter{T}"/> for the type
/// <typeparamref name="T"/>, to provide a fallback when the fast path cannot be used.
/// </summary>
Expand Down Expand Up @@ -75,10 +75,10 @@ internal override bool OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializer

if (!state.SupportContinuation &&
jsonTypeInfo is JsonTypeInfo<T> info &&
info.Serialize != null &&
info.SerializeHandler != null &&
info.Options._context?.CanUseSerializationLogic == true)
{
info.Serialize(writer, value);
info.SerializeHandler(writer, value);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace System.Text.Json.Serialization.Converters
/// Converter for JsonNode-derived types. The {T} value must be Object and not JsonNode
/// since we allow Object-declared members\variables to deserialize as {JsonNode}.
/// </summary>
internal sealed class JsonNodeConverter : JsonConverter<JsonNode?>
internal sealed class JsonNodeConverter : JsonConverter<JsonNode>
{
private static JsonNodeConverter? s_nodeConverter;
private static JsonArrayConverter? s_arrayConverter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ private static void WriteUsingGeneratedSerializer<TValue>(Utf8JsonWriter writer,
jsonTypeInfo is JsonTypeInfo<TValue> typedInfo &&
typedInfo.Options._context?.CanUseSerializationLogic == true)
{
Debug.Assert(typedInfo.Serialize != null);
typedInfo.Serialize(writer, value);
Debug.Assert(typedInfo.SerializeHandler != null);
typedInfo.SerializeHandler(writer, value);
writer.Flush();
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,36 @@ public static partial class JsonMetadataServices
public static JsonConverter<long> Int64Converter => s_int64Converter ??= new Int64Converter();
private static JsonConverter<long>? s_int64Converter;

/// <summary>
/// Returns a <see cref="JsonConverter{T}"/> instance that converts <see cref="JsonArray"/> values.
/// </summary>
public static JsonConverter<JsonArray> JsonArrayConverter => s_jsonArrayConverter ??= new JsonArrayConverter();
private static JsonConverter<JsonArray>? s_jsonArrayConverter;

/// <summary>
/// Returns a <see cref="JsonConverter{T}"/> instance that converts <see cref="JsonElement"/> values.
/// </summary>
public static JsonConverter<JsonElement> JsonElementConverter => s_jsonElementConverter ??= new JsonElementConverter();
private static JsonConverter<JsonElement>? s_jsonElementConverter;

/// <summary>
/// Returns a <see cref="JsonConverter{T}"/> instance that converts <see cref="JsonNode"/> values.
/// </summary>
public static JsonConverter<JsonNode> JsonNodeConverter => s_jsonNodeConverter ??= new JsonNodeConverter();
private static JsonConverter<JsonNode>? s_jsonNodeConverter;

/// <summary>
/// Returns a <see cref="JsonConverter{T}"/> instance that converts <see cref="JsonObject"/> values.
/// </summary>
public static JsonConverter<JsonObject> JsonObjectConverter => s_jsonObjectConverter ??= new JsonObjectConverter();
private static JsonConverter<JsonObject>? s_jsonObjectConverter;

/// <summary>
/// Returns a <see cref="JsonConverter{T}"/> instance that converts <see cref="JsonArray"/> values.
/// </summary>
public static JsonConverter<JsonValue> JsonValueConverter => s_jsonValueConverter ??= new JsonValueConverter();
private static JsonConverter<JsonValue>? s_jsonValueConverter;

/// <summary>
/// Returns a <see cref="JsonConverter{T}"/> instance that converts <see cref="object"/> values.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public JsonTypeInfoInternal(JsonSerializerOptions options, JsonObjectInfoValues<
#pragma warning restore CS8714

PropInitFunc = objectInfo.PropertyMetadataInitializer;
Serialize = objectInfo.SerializeHandler;
SerializeHandler = objectInfo.SerializeHandler;
PropertyInfoForTypeInfo = JsonMetadataServices.CreateJsonPropertyInfoForClassInfo(typeof(T), this, converter, Options);
NumberHandling = objectInfo.NumberHandling;
}
Expand Down Expand Up @@ -75,7 +75,7 @@ public JsonTypeInfoInternal(
ElementTypeInfo = collectionInfo.ElementInfo ?? throw new ArgumentNullException(nameof(collectionInfo.ElementInfo));
NumberHandling = collectionInfo.NumberHandling;
PropertyInfoForTypeInfo = JsonMetadataServices.CreateJsonPropertyInfoForClassInfo(typeof(T), this, converter, options);
Serialize = collectionInfo.SerializeHandler;
SerializeHandler = collectionInfo.SerializeHandler;
CreateObjectWithArgs = createObjectWithArgs;
AddMethodDelegate = addFunc;
SetCreateObjectFunc(collectionInfo.ObjectCreator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ internal JsonTypeInfo()
}

/// <summary>
/// A method that serializes an instance of <typeparamref name="T"/> using
/// Serializes an instance of <typeparamref name="T"/> using
/// <see cref="JsonSourceGenerationOptionsAttribute"/> values specified at design time.
/// </summary>
public Action<Utf8JsonWriter, T>? Serialize
/// <remarks>The writer is not flushed after writing.</remarks>
public Action<Utf8JsonWriter, T>? SerializeHandler
{
get
{
Expand Down
Loading