Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/coreclr/System.Private.CoreLib/src/System/Attribute.CoreCLR.cs16
-rw-r--r--src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs64
-rw-r--r--src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs6
-rw-r--r--src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Attribute.CoreRT.cs16
-rw-r--r--src/libraries/System.Reflection/tests/ParameterInfoTests.cs8
-rw-r--r--src/libraries/System.Runtime/tests/System/Attributes.cs100
-rw-r--r--src/tests/reflection/GenericAttribute/GenericAttributeMetadata.cs2
-rw-r--r--src/tests/reflection/GenericAttribute/GenericAttributeTests.cs14
8 files changed, 56 insertions, 170 deletions
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Attribute.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Attribute.CoreCLR.cs
index c84e918d843..f33849d2a94 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Attribute.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Attribute.CoreCLR.cs
@@ -434,8 +434,10 @@ namespace System
SR.Format(SR.Format_AttributeUsage, type));
}
- private static Attribute[] CreateAttributeArrayHelper(Type elementType, int elementCount) =>
- elementType.ContainsGenericParameters ? new Attribute[elementCount] : (Attribute[])Array.CreateInstance(elementType, elementCount);
+ private static Attribute[] CreateAttributeArrayHelper(Type elementType, int elementCount)
+ {
+ return (Attribute[])Array.CreateInstance(elementType, elementCount);
+ }
#endregion
#endregion
@@ -457,7 +459,7 @@ namespace System
{
MemberTypes.Property => InternalGetCustomAttributes((PropertyInfo)element, attributeType, inherit),
MemberTypes.Event => InternalGetCustomAttributes((EventInfo)element, attributeType, inherit),
- _ => (Attribute[])element.GetCustomAttributes(attributeType, inherit)
+ _ => (element.GetCustomAttributes(attributeType, inherit) as Attribute[])!,
};
}
@@ -472,7 +474,7 @@ namespace System
{
MemberTypes.Property => InternalGetCustomAttributes((PropertyInfo)element, typeof(Attribute), inherit),
MemberTypes.Event => InternalGetCustomAttributes((EventInfo)element, typeof(Attribute), inherit),
- _ => (Attribute[])element.GetCustomAttributes(typeof(Attribute), inherit)
+ _ => (element.GetCustomAttributes(typeof(Attribute), inherit) as Attribute[])!,
};
}
@@ -534,11 +536,12 @@ namespace System
if (element.Member == null)
throw new ArgumentException(SR.Argument_InvalidParameterInfo, nameof(element));
+
MemberInfo member = element.Member;
if (member.MemberType == MemberTypes.Method && inherit)
return InternalParamGetCustomAttributes(element, attributeType, inherit);
- return (Attribute[])element.GetCustomAttributes(attributeType, inherit);
+ return (element.GetCustomAttributes(attributeType, inherit) as Attribute[])!;
}
public static Attribute[] GetCustomAttributes(ParameterInfo element!!, bool inherit)
@@ -546,11 +549,12 @@ namespace System
if (element.Member == null)
throw new ArgumentException(SR.Argument_InvalidParameterInfo, nameof(element));
+
MemberInfo member = element.Member;
if (member.MemberType == MemberTypes.Method && inherit)
return InternalParamGetCustomAttributes(element, null, inherit);
- return (Attribute[])element.GetCustomAttributes(typeof(Attribute), inherit);
+ return (element.GetCustomAttributes(typeof(Attribute), inherit) as Attribute[])!;
}
public static bool IsDefined(ParameterInfo element, Type attributeType)
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs
index d28edee2403..bb642f913da 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs
@@ -899,7 +899,7 @@ namespace System.Reflection
Debug.Assert(caType is not null);
if (type.GetElementType() is not null)
- return CreateAttributeArrayHelper(caType, 0);
+ return (caType.IsValueType) ? Array.Empty<object>() : CreateAttributeArrayHelper(caType, 0);
if (type.IsGenericType && !type.IsGenericTypeDefinition)
type = (type.GetGenericTypeDefinition() as RuntimeType)!;
@@ -919,6 +919,8 @@ namespace System.Reflection
RuntimeType.ListBuilder<object> result = default;
bool mustBeInheritable = false;
+ bool useObjectArray = (caType.IsValueType || caType.ContainsGenericParameters);
+ RuntimeType arrayType = useObjectArray ? (RuntimeType)typeof(object) : caType;
for (int i = 0; i < pcas.Count; i++)
result.Add(pcas[i]);
@@ -930,7 +932,7 @@ namespace System.Reflection
type = (type.BaseType as RuntimeType)!;
}
- object[] typedResult = CreateAttributeArrayHelper(caType, result.Count);
+ object[] typedResult = CreateAttributeArrayHelper(arrayType, result.Count);
for (int i = 0; i < result.Count; i++)
{
typedResult[i] = result[i];
@@ -961,6 +963,8 @@ namespace System.Reflection
RuntimeType.ListBuilder<object> result = default;
bool mustBeInheritable = false;
+ bool useObjectArray = (caType.IsValueType || caType.ContainsGenericParameters);
+ RuntimeType arrayType = useObjectArray ? (RuntimeType)typeof(object) : caType;
for (int i = 0; i < pcas.Count; i++)
result.Add(pcas[i]);
@@ -972,7 +976,7 @@ namespace System.Reflection
method = method.GetParentDefinition()!;
}
- object[] typedResult = CreateAttributeArrayHelper(caType, result.Count);
+ object[] typedResult = CreateAttributeArrayHelper(arrayType, result.Count);
for (int i = 0; i < result.Count; i++)
{
typedResult[i] = result[i];
@@ -1119,13 +1123,16 @@ namespace System.Reflection
}
private static object[] GetCustomAttributes(
- RuntimeModule decoratedModule, int decoratedMetadataToken, int pcaCount, RuntimeType attributeFilterType)
+ RuntimeModule decoratedModule, int decoratedMetadataToken, int pcaCount, RuntimeType? attributeFilterType)
{
RuntimeType.ListBuilder<object> attributes = default;
AddCustomAttributes(ref attributes, decoratedModule, decoratedMetadataToken, attributeFilterType, false, default);
- object[] result = CreateAttributeArrayHelper(attributeFilterType, attributes.Count + pcaCount);
+ bool useObjectArray = attributeFilterType is null || attributeFilterType.IsValueType || attributeFilterType.ContainsGenericParameters;
+ RuntimeType arrayType = useObjectArray ? (RuntimeType)typeof(object) : attributeFilterType!;
+
+ object[] result = CreateAttributeArrayHelper(arrayType, attributes.Count + pcaCount);
for (int i = 0; i < attributes.Count; i++)
{
result[i] = attributes[i];
@@ -1432,42 +1439,6 @@ namespace System.Reflection
return attributeUsageAttribute ?? AttributeUsageAttribute.Default;
}
-
- internal static object[] CreateAttributeArrayHelper(RuntimeType caType, int elementCount)
- {
- bool useAttributeArray = false;
- bool useObjectArray = false;
-
- if (caType == typeof(Attribute))
- {
- useAttributeArray = true;
- }
- else if (caType.IsValueType)
- {
- useObjectArray = true;
- }
- else if (caType.ContainsGenericParameters)
- {
- if (caType.IsSubclassOf(typeof(Attribute)))
- {
- useAttributeArray = true;
- }
- else
- {
- useObjectArray = true;
- }
- }
-
- if (useAttributeArray)
- {
- return elementCount == 0 ? Array.Empty<Attribute>() : new Attribute[elementCount];
- }
- if (useObjectArray)
- {
- return elementCount == 0 ? Array.Empty<object>() : new object[elementCount];
- }
- return elementCount == 0 ? caType.GetEmptyArray() : (object[])Array.CreateInstance(caType, elementCount);
- }
#endregion
#region Private Static FCalls
@@ -1505,6 +1476,17 @@ namespace System.Reflection
module, &pBlobStart, (byte*)blobEnd, out name, out isProperty, out type, out value);
blobStart = (IntPtr)pBlobStart;
}
+
+ private static object[] CreateAttributeArrayHelper(RuntimeType elementType, int elementCount)
+ {
+ // If we have 0 elements, don't allocate a new array
+ if (elementCount == 0)
+ {
+ return elementType.GetEmptyArray();
+ }
+
+ return (object[])Array.CreateInstance(elementType, elementCount);
+ }
#endregion
}
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs
index f889133b531..33777c745db 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs
@@ -509,12 +509,12 @@ namespace System.Reflection
public override object[] GetCustomAttributes(Type attributeType!!, bool inherit)
{
+ if (MdToken.IsNullToken(m_tkParamDef))
+ return Array.Empty<object>();
+
if (attributeType.UnderlyingSystemType is not RuntimeType attributeRuntimeType)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
- if (MdToken.IsNullToken(m_tkParamDef))
- return CustomAttribute.CreateAttributeArrayHelper(attributeRuntimeType, 0);
-
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Attribute.CoreRT.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Attribute.CoreRT.cs
index f7604612b5a..d7f9bb693ea 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Attribute.CoreRT.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Attribute.CoreRT.cs
@@ -141,9 +141,19 @@ namespace System
attributes.Add(instantiatedAttribute);
}
int count = attributes.Count;
- Attribute[] result = actualElementType.ContainsGenericParameters
- ? new Attribute[count]
- : (Attribute[])Array.CreateInstance(actualElementType, count);
+ Attribute[] result;
+ try
+ {
+ result = (Attribute[])Array.CreateInstance(actualElementType, count);
+ }
+ catch (NotSupportedException) when (actualElementType.ContainsGenericParameters)
+ {
+ // This is here for desktop compatibility (using try-catch as control flow to avoid slowing down the mainline case.)
+ // GetCustomAttributes() normally returns an array of the exact attribute type requested except when
+ // the requested type is an open type. Its ICustomAttributeProvider counterpart would return an Object[] array but that's
+ // not possible with this api's return type so it returns null instead.
+ return null;
+ }
attributes.CopyTo(result, 0);
return result;
}
diff --git a/src/libraries/System.Reflection/tests/ParameterInfoTests.cs b/src/libraries/System.Reflection/tests/ParameterInfoTests.cs
index 26d2d65867f..f6285546a87 100644
--- a/src/libraries/System.Reflection/tests/ParameterInfoTests.cs
+++ b/src/libraries/System.Reflection/tests/ParameterInfoTests.cs
@@ -246,14 +246,6 @@ namespace System.Reflection.Tests
}
[Fact]
- public static void GetCustomAttributesOnParameterWithNullMetadataTokenReturnsArrayOfCorrectType()
- {
- var parameterWithNullMetadataToken = typeof(int[]).GetProperty(nameof(Array.Length)).GetMethod.ReturnParameter;
- Assert.Equal(typeof(Attribute[]), Attribute.GetCustomAttributes(parameterWithNullMetadataToken).GetType());
- Assert.Equal(typeof(MyAttribute[]), Attribute.GetCustomAttributes(parameterWithNullMetadataToken, typeof(MyAttribute)).GetType());
- }
-
- [Fact]
public void VerifyGetCustomAttributesData()
{
ParameterInfo p = GetParameterInfo(typeof(ParameterInfoMetadata), "MethodWithCustomAttribute", 0);
diff --git a/src/libraries/System.Runtime/tests/System/Attributes.cs b/src/libraries/System.Runtime/tests/System/Attributes.cs
index 3dda3f56b35..e219d30a2be 100644
--- a/src/libraries/System.Runtime/tests/System/Attributes.cs
+++ b/src/libraries/System.Runtime/tests/System/Attributes.cs
@@ -20,7 +20,7 @@ using System.Diagnostics;
using System.Runtime.InteropServices;
using Xunit;
-[module: Debuggable(true, false)]
+[module:Debuggable(true,false)]
namespace System.Tests
{
public class AttributeIsDefinedTests
@@ -218,71 +218,6 @@ namespace System.Tests
{
Assert.True(typeof(ExampleWithAttribute).GetCustomAttributes(typeof(INameable), inherit: false)[0] is NameableAttribute);
}
-
- [Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/56887)", TestRuntimes.Mono)]
- public static void GetCustomAttributesWorksWithOpenAndClosedGenericTypesForType()
- {
- GenericAttributesTestHelper<string>(t => Attribute.GetCustomAttributes(typeof(HasGenericAttribute), t));
- }
-
- [Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/56887)", TestRuntimes.Mono)]
- public static void GetCustomAttributesWorksWithOpenAndClosedGenericTypesForField()
- {
- FieldInfo field = typeof(HasGenericAttribute).GetField(nameof(HasGenericAttribute.Field), BindingFlags.NonPublic | BindingFlags.Instance);
- GenericAttributesTestHelper<TimeSpan>(t => Attribute.GetCustomAttributes(field, t));
- }
-
- [Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/56887)", TestRuntimes.Mono)]
- public static void GetCustomAttributesWorksWithOpenAndClosedGenericTypesForConstructor()
- {
- ConstructorInfo method = typeof(HasGenericAttribute).GetConstructor(Type.EmptyTypes);
- GenericAttributesTestHelper<Guid>(t => Attribute.GetCustomAttributes(method, t));
- }
-
- [Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/56887)", TestRuntimes.Mono)]
- public static void GetCustomAttributesWorksWithOpenAndClosedGenericTypesForMethod()
- {
- MethodInfo method = typeof(HasGenericAttribute).GetMethod(nameof(HasGenericAttribute.Method));
- GenericAttributesTestHelper<long>(t => Attribute.GetCustomAttributes(method, t));
- }
-
- [Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/56887)", TestRuntimes.Mono)]
- public static void GetCustomAttributesWorksWithOpenAndClosedGenericTypesForParameter()
- {
- ParameterInfo parameter = typeof(HasGenericAttribute).GetMethod(nameof(HasGenericAttribute.Method)).GetParameters()[0];
- GenericAttributesTestHelper<ulong>(t => Attribute.GetCustomAttributes(parameter, t));
- }
-
- [Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/56887)", TestRuntimes.Mono)]
- public static void GetCustomAttributesWorksWithOpenAndClosedGenericTypesForProperty()
- {
- PropertyInfo property = typeof(HasGenericAttribute).GetProperty(nameof(HasGenericAttribute.Property));
- GenericAttributesTestHelper<List<object>>(t => Attribute.GetCustomAttributes(property, t));
- }
-
- [Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/56887)", TestRuntimes.Mono)]
- public static void GetCustomAttributesWorksWithOpenAndClosedGenericTypesForEvent()
- {
- EventInfo @event = typeof(HasGenericAttribute).GetEvent(nameof(HasGenericAttribute.Event));
- GenericAttributesTestHelper<DateTime?>(t => Attribute.GetCustomAttributes(@event, t));
- }
-
- private static void GenericAttributesTestHelper<TGenericParameter>(Func<Type, Attribute[]> getCustomAttributes)
- {
- Attribute[] openGenericAttributes = getCustomAttributes(typeof(GenericAttribute<>));
- Assert.Empty(openGenericAttributes);
-
- Attribute[] closedGenericAttributes = getCustomAttributes(typeof(GenericAttribute<TGenericParameter>));
- Assert.Equal(1, closedGenericAttributes.Length);
- Assert.Equal(typeof(GenericAttribute<TGenericParameter>[]), closedGenericAttributes.GetType());
- }
}
public static class GetCustomAttribute
@@ -291,7 +226,7 @@ namespace System.Tests
[Fact]
public static void customAttributeCount()
{
- List<CustomAttributeData> customAttributes = typeof(GetCustomAttribute).Module.CustomAttributes.ToList();
+ List<CustomAttributeData> customAttributes = typeof(GetCustomAttribute).Module.CustomAttributes.ToList();
// [System.Security.UnverifiableCodeAttribute()]
// [TestAttributes.FooAttribute()]
// [TestAttributes.ComplicatedAttribute((Int32)1, Stuff = 2)]
@@ -725,7 +660,7 @@ namespace System.Tests
}
public class BaseClass
{
- public virtual void TestMethod([ArgumentUsage("for test")] string[] strArray, params string[] strList)
+ public virtual void TestMethod([ArgumentUsage("for test")]string[] strArray, params string[] strList)
{
}
}
@@ -881,7 +816,7 @@ namespace System.Tests
string Name { get; }
}
- [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
+ [AttributeUsage (AttributeTargets.All, AllowMultiple = true)]
public class NameableAttribute : Attribute, INameable
{
string INameable.Name => "Nameable";
@@ -889,31 +824,4 @@ namespace System.Tests
[Nameable]
public class ExampleWithAttribute { }
-
- public class GenericAttribute<T> : Attribute
- {
- }
-
- [GenericAttribute<string>]
- public class HasGenericAttribute
- {
- [GenericAttribute<TimeSpan>]
- internal bool Field;
-
- [GenericAttribute<Guid>]
- public HasGenericAttribute() { }
-
- [GenericAttribute<long>]
- public void Method([GenericAttribute<ulong>] int parameter)
- {
- this.Field = true;
- this.Event += () => { };
- }
-
- [GenericAttribute<List<object>>]
- public int Property { get; set; }
-
- [GenericAttribute<DateTime?>]
- public event Action Event;
- }
}
diff --git a/src/tests/reflection/GenericAttribute/GenericAttributeMetadata.cs b/src/tests/reflection/GenericAttribute/GenericAttributeMetadata.cs
index 3bea1e62194..d0ef6353f4a 100644
--- a/src/tests/reflection/GenericAttribute/GenericAttributeMetadata.cs
+++ b/src/tests/reflection/GenericAttribute/GenericAttributeMetadata.cs
@@ -17,8 +17,6 @@ using System.Runtime.CompilerServices;
[assembly: MultiAttribute<bool>()]
[assembly: MultiAttribute<bool>(true)]
-[module: SingleAttribute<long>()]
-
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false)]
public class SingleAttribute<T> : Attribute
{
diff --git a/src/tests/reflection/GenericAttribute/GenericAttributeTests.cs b/src/tests/reflection/GenericAttribute/GenericAttributeTests.cs
index b1dcd6bbbe3..e7661d2d5ae 100644
--- a/src/tests/reflection/GenericAttribute/GenericAttributeTests.cs
+++ b/src/tests/reflection/GenericAttribute/GenericAttributeTests.cs
@@ -18,16 +18,8 @@ class Program
Assert(((ICustomAttributeProvider)assembly).IsDefined(typeof(SingleAttribute<int>), true));
Assert(CustomAttributeExtensions.IsDefined(assembly, typeof(SingleAttribute<bool>)));
Assert(((ICustomAttributeProvider)assembly).IsDefined(typeof(SingleAttribute<bool>), true));
- Assert(!CustomAttributeExtensions.GetCustomAttributes(assembly, typeof(SingleAttribute<>)).GetEnumerator().MoveNext());
- Assert(!CustomAttributeExtensions.GetCustomAttributes(assembly, typeof(SingleAttribute<>)).GetEnumerator().MoveNext());
-*/
- // Module module = programTypeInfo.Module;
- // AssertAny(CustomAttributeExtensions.GetCustomAttributes(module), a => a is SingleAttribute<long>);
- // Assert(CustomAttributeExtensions.GetCustomAttributes(module, typeof(SingleAttribute<long>)).GetEnumerator().MoveNext());
- // Assert(CustomAttributeExtensions.GetCustomAttributes(module, typeof(SingleAttribute<long>)).GetEnumerator().MoveNext());
- // Assert(!CustomAttributeExtensions.GetCustomAttributes(module, typeof(SingleAttribute<>)).GetEnumerator().MoveNext());
- // Assert(!CustomAttributeExtensions.GetCustomAttributes(module, typeof(SingleAttribute<>)).GetEnumerator().MoveNext());
+*/
TypeInfo programTypeInfo = typeof(Class).GetTypeInfo();
Assert(CustomAttributeExtensions.GetCustomAttribute<SingleAttribute<int>>(programTypeInfo) != null);
@@ -160,8 +152,8 @@ class Program
AssertAny(b10, a => (a as MultiAttribute<Type>)?.Value == typeof(Class));
AssertAny(b10, a => (a as MultiAttribute<Type>)?.Value == typeof(Class.Derive));
- Assert(!CustomAttributeExtensions.GetCustomAttributes(programTypeInfo, typeof(MultiAttribute<>), false).GetEnumerator().MoveNext());
- Assert(!CustomAttributeExtensions.GetCustomAttributes(programTypeInfo, typeof(MultiAttribute<>), true).GetEnumerator().MoveNext());
+ Assert(CustomAttributeExtensions.GetCustomAttributes(programTypeInfo, typeof(MultiAttribute<>), false) == null);
+ Assert(CustomAttributeExtensions.GetCustomAttributes(programTypeInfo, typeof(MultiAttribute<>), true) == null);
Assert(!((ICustomAttributeProvider)programTypeInfo).GetCustomAttributes(typeof(MultiAttribute<>), true).GetEnumerator().MoveNext());
// Test coverage for CustomAttributeData api surface