m_scope = scope;
m_ctor = (RuntimeConstructorInfo)RuntimeType.GetMethodBase(scope, caCtorToken)!;
+ if (m_ctor!.DeclaringType!.IsGenericType)
+ {
+ MetadataImport metadataScope = scope.MetadataImport;
+ var attributeType = scope.ResolveType(metadataScope.GetParentToken(caCtorToken), null, null)!;
+ m_ctor = (RuntimeConstructorInfo)scope.ResolveMethod(caCtorToken, attributeType.GenericTypeArguments, null)!.MethodHandle.GetMethodInfo();
+ }
+
ParameterInfo[] parameters = m_ctor.GetParametersNoCopy();
m_ctorParams = new CustomAttributeCtorParameter[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )
-
+/* Re-enable once the fix to https://github.com/dotnet/msbuild/issues/6734 propagates to this repo.
.custom instance void class SingleAttribute`1<int32>::.ctor() = ( 01 00 00 00 )
.custom instance void class SingleAttribute`1<bool>::.ctor() = ( 01 00 00 00 )
.custom instance void class MultiAttribute`1<int32>::.ctor() = ( 01 00 00 00 )
.custom instance void class MultiAttribute`1<int32>::.ctor(!0) = ( 01 00 01 00 00 00 00 00 )
.custom instance void class MultiAttribute`1<int32>::.ctor() = ( 01 00 01 00 54 08 05 56 61 6C 75 65 02 00 00 00 ) // ....T..Value....
.custom instance void class MultiAttribute`1<bool>::.ctor() = ( 01 00 00 00 )
- .custom instance void class MultiAttribute`1<bool>::.ctor(!0) = ( 01 00 01 00 00 )
+ .custom instance void class MultiAttribute`1<bool>::.ctor(!0) = ( 01 00 01 00 00 ) */
.hash algorithm 0x00008004
.ver 0:0:0:0
}
{
static int Main(string[] args)
{
+/* Re-enable once the fix to https://github.com/dotnet/msbuild/issues/6734 propagates to this repo.
Assembly assembly = typeof(Class).GetTypeInfo().Assembly;
Assert(CustomAttributeExtensions.GetCustomAttribute<SingleAttribute<int>>(assembly) != null);
Assert(((ICustomAttributeProvider)assembly).GetCustomAttributes(typeof(SingleAttribute<int>), true) != null);
Assert(CustomAttributeExtensions.IsDefined(assembly, typeof(SingleAttribute<bool>)));
Assert(((ICustomAttributeProvider)assembly).IsDefined(typeof(SingleAttribute<bool>), true));
+*/
+
TypeInfo programTypeInfo = typeof(Class).GetTypeInfo();
Assert(CustomAttributeExtensions.GetCustomAttribute<SingleAttribute<int>>(programTypeInfo) != null);
Assert(((ICustomAttributeProvider)programTypeInfo).GetCustomAttributes(typeof(SingleAttribute<int>), true) != null);
Assert(CustomAttributeExtensions.GetCustomAttributes(programTypeInfo, typeof(MultiAttribute<>), true) == null);
Assert(!((ICustomAttributeProvider)programTypeInfo).GetCustomAttributes(typeof(MultiAttribute<>), true).GetEnumerator().MoveNext());
+ // Test coverage for CustomAttributeData api surface
+ var a1_data = CustomAttributeData.GetCustomAttributes(programTypeInfo);
+ AssertAny(a1_data, a => a.AttributeType == typeof(SingleAttribute<int>));
+ AssertAny(a1_data, a => a.AttributeType == typeof(SingleAttribute<bool>));
+
+ AssertAny(a1_data, a => a.AttributeType == typeof(MultiAttribute<int>) && a.ConstructorArguments.Count == 0 && a.NamedArguments.Count == 0);
+ AssertAny(a1_data, a => a.AttributeType == typeof(MultiAttribute<int>) && a.ConstructorArguments.Count == 1 && a.NamedArguments.Count == 0 && a.ConstructorArguments[0].ArgumentType == typeof(int) && ((int)a.ConstructorArguments[0].Value) == 1);
+ AssertAny(a1_data, a => a.AttributeType == typeof(MultiAttribute<int>) && a.ConstructorArguments.Count == 0 && a.NamedArguments.Count == 1 && a.NamedArguments[0].TypedValue.ArgumentType == typeof(int) && ((int)a.NamedArguments[0].TypedValue.Value) == 2);
+
+ AssertAny(a1_data, a => a.AttributeType == typeof(MultiAttribute<bool>) && a.ConstructorArguments.Count == 0 && a.NamedArguments.Count == 0);
+ AssertAny(a1_data, a => a.AttributeType == typeof(MultiAttribute<bool>) && a.ConstructorArguments.Count == 1 && a.NamedArguments.Count == 0 && a.ConstructorArguments[0].ArgumentType == typeof(bool) && ((bool)a.ConstructorArguments[0].Value) == true);
+ AssertAny(a1_data, a => a.AttributeType == typeof(MultiAttribute<bool>) && a.ConstructorArguments.Count == 0 && a.NamedArguments.Count == 1 && a.NamedArguments[0].TypedValue.ArgumentType == typeof(bool) && ((bool)a.NamedArguments[0].TypedValue.Value) == true);
+
+ AssertAny(a1_data, a => a.AttributeType == typeof(MultiAttribute<bool?>) && a.ConstructorArguments.Count == 0 && a.NamedArguments.Count == 0);
+
+ AssertAny(a1_data, a => a.AttributeType == typeof(MultiAttribute<Type>) && a.ConstructorArguments.Count == 1 && a.NamedArguments.Count == 0 && a.ConstructorArguments[0].ArgumentType == typeof(Type) && ((Type)a.ConstructorArguments[0].Value) == typeof(Class));
+ AssertAny(a1_data, a => a.AttributeType == typeof(MultiAttribute<Type>) && a.ConstructorArguments.Count == 0 && a.NamedArguments.Count == 1 && a.NamedArguments[0].TypedValue.ArgumentType == typeof(Type) && ((Type)a.NamedArguments[0].TypedValue.Value) == typeof(Class.Derive));
+
return 100;
}
}
throw new Exception($"Error in line: {line}");
}
+
+ static void AssertAny(IEnumerable<CustomAttributeData> source, Func<CustomAttributeData, bool> condition, int count = 1, [CallerLineNumberAttribute]int line = 0)
+ {
+ var enumerator = source.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ if(condition(enumerator.Current) && --count == 0)
+ {
+ return;
+ }
+ }
+ throw new Exception($"Error in line: {line}");
+ }
}