Skip to content

Commit

Permalink
Add linker annotations for System.Text.Json (#38595)
Browse files Browse the repository at this point in the history
* Add linker annotations for System.Text.Json

* Review feedback - don't use property accessors in tests and use normal await pattern

* Add annotations to ref & fix immutable collections

* Address review feedback

* Clean up linker tests

* Fix ref file #if directives

* Clean up

* Re-add Hastable.cs

* Remove serialization code from Deserialize overload tests

* Verify collection deserialization is correct
  • Loading branch information
layomia authored Jul 7, 2020
1 parent 9f4d39a commit d43299d
Show file tree
Hide file tree
Showing 76 changed files with 2,122 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ namespace System.Diagnostics.CodeAnalysis
AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter |
AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method,
Inherited = false)]
public sealed class DynamicallyAccessedMembersAttribute : Attribute
#if SYSTEM_PRIVATE_CORELIB
public
#else
internal
#endif
sealed class DynamicallyAccessedMembersAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="DynamicallyAccessedMembersAttribute"/> class
Expand Down
30 changes: 30 additions & 0 deletions src/libraries/System.Text.Json/ref/System.Text.Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,29 @@ public partial struct JsonReaderState
}
public static partial class JsonSerializer
{
#if NETCOREAPP
private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnRead = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties;
private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnWrite = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties;
public static object? Deserialize(System.ReadOnlySpan<byte> utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static object? Deserialize(string json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static System.Threading.Tasks.ValueTask<object?> DeserializeAsync(System.IO.Stream utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public static System.Threading.Tasks.ValueTask<TValue> DeserializeAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
[return: System.Diagnostics.CodeAnalysis.MaybeNull]
public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.ReadOnlySpan<byte> utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
[return: System.Diagnostics.CodeAnalysis.MaybeNull]
public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
[return: System.Diagnostics.CodeAnalysis.MaybeNull]
public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static string Serialize(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { }
public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public static System.Threading.Tasks.Task SerializeAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(System.IO.Stream utf8Json, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public static byte[] SerializeToUtf8Bytes(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static byte[] SerializeToUtf8Bytes<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static void Serialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { }
public static string Serialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
#else
public static object? Deserialize(System.ReadOnlySpan<byte> utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static object? Deserialize(string json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
Expand All @@ -204,6 +227,7 @@ public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? val
public static byte[] SerializeToUtf8Bytes<TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static void Serialize<TValue>(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { }
public static string Serialize<TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
#endif
}
public sealed partial class JsonSerializerOptions
{
Expand Down Expand Up @@ -483,8 +507,14 @@ internal JsonConverter() { }
public partial class JsonConverterAttribute : System.Text.Json.Serialization.JsonAttribute
{
protected JsonConverterAttribute() { }
#if NETCOREAPP
public JsonConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] System.Type converterType) { }
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
public System.Type? ConverterType { get { throw null; } }
#else
public JsonConverterAttribute(System.Type converterType) { }
public System.Type? ConverterType { get { throw null; } }
#endif
public virtual System.Text.Json.Serialization.JsonConverter? CreateConverter(System.Type typeToConvert) { throw null; }
}
public abstract partial class JsonConverterFactory : System.Text.Json.Serialization.JsonConverter
Expand Down
1 change: 1 addition & 0 deletions src/libraries/System.Text.Json/src/System.Text.Json.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\DynamicDependencyAttribute.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\DynamicallyAccessedMembersAttribute.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\DynamicallyAccessedMemberTypes.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics.CodeAnalysis;

namespace System.Text.Json.Serialization
{
/// <summary>
Expand All @@ -21,7 +23,7 @@ public class JsonConverterAttribute : JsonAttribute
/// Initializes a new instance of <see cref="JsonConverterAttribute"/> with the specified converter type.
/// </summary>
/// <param name="converterType">The type of the converter.</param>
public JsonConverterAttribute(Type converterType)
public JsonConverterAttribute([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type converterType)
{
ConverterType = converterType;
}
Expand All @@ -34,6 +36,7 @@ protected JsonConverterAttribute() { }
/// <summary>
/// The type of the converter to create, or null if <see cref="CreateConverter(Type)"/> should be used to obtain the converter.
/// </summary>
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
public Type? ConverterType { get; private set; }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;

namespace System.Text.Json.Serialization.Converters
Expand All @@ -25,23 +24,6 @@ public override bool CanConvert(Type typeToConvert)
return typeof(IEnumerable).IsAssignableFrom(typeToConvert);
}

[DynamicDependency("#ctor", typeof(ArrayConverter<,>))]
[DynamicDependency("#ctor", typeof(ConcurrentQueueOfTConverter<,>))]
[DynamicDependency("#ctor", typeof(ConcurrentStackOfTConverter<,>))]
[DynamicDependency("#ctor", typeof(DictionaryOfTKeyTValueConverter<,,>))]
[DynamicDependency("#ctor", typeof(ICollectionOfTConverter<,>))]
[DynamicDependency("#ctor", typeof(IDictionaryOfTKeyTValueConverter<,,>))]
[DynamicDependency("#ctor", typeof(IEnumerableOfTConverter<,>))]
[DynamicDependency("#ctor", typeof(IEnumerableWithAddMethodConverter<>))]
[DynamicDependency("#ctor", typeof(IListConverter<>))]
[DynamicDependency("#ctor", typeof(IListOfTConverter<,>))]
[DynamicDependency("#ctor", typeof(ImmutableDictionaryOfTKeyTValueConverter<,,>))]
[DynamicDependency("#ctor", typeof(ImmutableEnumerableOfTConverter<,>))]
[DynamicDependency("#ctor", typeof(IReadOnlyDictionaryOfTKeyTValueConverter<,,>))]
[DynamicDependency("#ctor", typeof(ISetOfTConverter<,>))]
[DynamicDependency("#ctor", typeof(ListOfTConverter<,>))]
[DynamicDependency("#ctor", typeof(QueueOfTConverter<,>))]
[DynamicDependency("#ctor", typeof(StackOfTConverter<,>))]
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
Type converterType;
Expand Down
Loading

0 comments on commit d43299d

Please sign in to comment.