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

[release/6.0] Fix nullable annotations for AssociatedMetadataTypeTypeDescriptionProvider #57979

Merged
merged 1 commit into from
Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@

namespace System.ComponentModel.DataAnnotations
{
// TODO-NULLABLE: Enable after System.ComponentModel.TypeDescriptionProvider is annotated
#nullable disable
public partial class AssociatedMetadataTypeTypeDescriptionProvider : System.ComponentModel.TypeDescriptionProvider
{
public AssociatedMetadataTypeTypeDescriptionProvider(System.Type type) { }
public AssociatedMetadataTypeTypeDescriptionProvider(System.Type type, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type associatedMetadataType) { }
public override System.ComponentModel.ICustomTypeDescriptor GetTypeDescriptor([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type objectType, object instance) { throw null; }
public override System.ComponentModel.ICustomTypeDescriptor GetTypeDescriptor([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type objectType, object? instance) { throw null; }
}
#nullable enable
[System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)]
[System.ObsoleteAttribute("AssociationAttribute has been deprecated and is not supported.")]
public sealed partial class AssociationAttribute : System.Attribute
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// TODO-NULLABLE: Enable after System.ComponentModel.TypeDescriptionProvider is annotated
#nullable disable

using System.Diagnostics.CodeAnalysis;

namespace System.ComponentModel.DataAnnotations
Expand All @@ -15,7 +12,7 @@ namespace System.ComponentModel.DataAnnotations
public class AssociatedMetadataTypeTypeDescriptionProvider : TypeDescriptionProvider
{
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
private readonly Type _associatedMetadataType;
private readonly Type? _associatedMetadataType;

/// <summary>
/// Initializes a new instance of the System.ComponentModel.DataAnnotations.AssociatedMetadataTypeTypeDescriptionProvider
Expand Down Expand Up @@ -53,9 +50,9 @@ public AssociatedMetadataTypeTypeDescriptionProvider(
/// <param name="objectType">The type of object to retrieve the type descriptor for.</param>
/// <param name="instance">An instance of the type.</param>
/// <returns>The descriptor that provides metadata for the type.</returns>
public override ICustomTypeDescriptor GetTypeDescriptor([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type objectType, object instance)
public override ICustomTypeDescriptor GetTypeDescriptor([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type objectType, object? instance)
{
ICustomTypeDescriptor baseDescriptor = base.GetTypeDescriptor(objectType, instance);
ICustomTypeDescriptor? baseDescriptor = base.GetTypeDescriptor(objectType, instance);
return new AssociatedMetadataTypeTypeDescriptor(baseDescriptor, objectType, _associatedMetadataType);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// TODO-NULLABLE: Enable after System.ComponentModel.TypeDescriptionProvider is annotated
#nullable disable

using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
Expand All @@ -15,14 +12,14 @@ namespace System.ComponentModel.DataAnnotations
internal sealed class AssociatedMetadataTypeTypeDescriptor : CustomTypeDescriptor
{
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
private Type AssociatedMetadataType { get; set; }
private Type? AssociatedMetadataType { get; set; }

private bool IsSelfAssociated { get; set; }

public AssociatedMetadataTypeTypeDescriptor(
ICustomTypeDescriptor parent,
ICustomTypeDescriptor? parent,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type associatedMetadataType)
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? associatedMetadataType)
: base(parent)
{
AssociatedMetadataType = associatedMetadataType ?? TypeDescriptorCache.GetAssociatedMetadataType(type);
Expand All @@ -34,7 +31,7 @@ public AssociatedMetadataTypeTypeDescriptor(
}

[RequiresUnreferencedCode("PropertyDescriptor's PropertyType cannot be statically discovered. The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")]
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
public override PropertyDescriptorCollection GetProperties(Attribute[]? attributes)
{
return GetPropertiesWithMetadata(base.GetProperties(attributes));
}
Expand Down Expand Up @@ -96,7 +93,7 @@ public override AttributeCollection GetAttributes()
private static class TypeDescriptorCache
{
// Stores the associated metadata type for a type
private static readonly ConcurrentDictionary<Type, Type> s_metadataTypeCache = new ConcurrentDictionary<Type, Type>();
private static readonly ConcurrentDictionary<Type, Type?> s_metadataTypeCache = new ConcurrentDictionary<Type, Type?>();

// Stores the attributes for a member info
private static readonly ConcurrentDictionary<(Type, string), Attribute[]> s_typeMemberCache = new ConcurrentDictionary<(Type, string), Attribute[]>();
Expand All @@ -117,16 +114,16 @@ public static void ValidateMetadataType(
}

[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public static Type GetAssociatedMetadataType(Type type)
public static Type? GetAssociatedMetadataType(Type type)
{
Type associatedMetadataType = null;
Type? associatedMetadataType;
if (s_metadataTypeCache.TryGetValue(type, out associatedMetadataType))
{
return associatedMetadataType;
}

// Try association attribute
MetadataTypeAttribute attribute = (MetadataTypeAttribute)Attribute.GetCustomAttribute(type, typeof(MetadataTypeAttribute));
MetadataTypeAttribute? attribute = (MetadataTypeAttribute?)Attribute.GetCustomAttribute(type, typeof(MetadataTypeAttribute));
if (attribute != null)
{
associatedMetadataType = attribute.MetadataClassType;
Expand Down Expand Up @@ -164,7 +161,7 @@ public static Attribute[] GetAssociatedMetadata(
string memberName)
{
(Type, string) memberTuple = (type, memberName);
Attribute[] attributes;
Attribute[]? attributes;
if (s_typeMemberCache.TryGetValue(memberTuple, out attributes))
{
return attributes;
Expand All @@ -175,7 +172,7 @@ public static Attribute[] GetAssociatedMetadata(
// Only public static/instance members
BindingFlags searchFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
// Try to find a matching member on type
MemberInfo matchingMember = type.GetMember(memberName, allowedMemberTypes, searchFlags).FirstOrDefault();
MemberInfo? matchingMember = type.GetMember(memberName, allowedMemberTypes, searchFlags).FirstOrDefault();
if (matchingMember != null)
{
attributes = Attribute.GetCustomAttributes(matchingMember, true /* inherit */);
Expand Down