Skip to content

Commit 42b9ef1

Browse files
authored
Add support for generic attributes (#871)
* Add support for generic attributes * Compile test assembly against mscorlib To satisfy PEVerify
1 parent 49b1c52 commit 42b9ef1

File tree

4 files changed

+84
-4
lines changed

4 files changed

+84
-4
lines changed

Mono.Cecil/AssemblyReader.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -3513,9 +3513,12 @@ public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute,
35133513

35143514
attribute.arguments = new Collection<CustomAttributeArgument> (count);
35153515

3516-
for (int i = 0; i < count; i++)
3516+
for (int i = 0; i < count; i++) {
3517+
var parameterType = GenericParameterResolver.ResolveParameterTypeIfNeeded (
3518+
attribute.Constructor, parameters [i]);
35173519
attribute.arguments.Add (
3518-
ReadCustomAttributeFixedArgument (parameters [i].ParameterType));
3520+
ReadCustomAttributeFixedArgument (parameterType));
3521+
}
35193522
}
35203523

35213524
CustomAttributeArgument ReadCustomAttributeFixedArgument (TypeReference type)

Mono.Cecil/AssemblyWriter.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -2922,8 +2922,11 @@ public void WriteCustomAttributeConstructorArguments (CustomAttribute attribute)
29222922
if (parameters.Count != arguments.Count)
29232923
throw new InvalidOperationException ();
29242924

2925-
for (int i = 0; i < arguments.Count; i++)
2926-
WriteCustomAttributeFixedArgument (parameters [i].ParameterType, arguments [i]);
2925+
for (int i = 0; i < arguments.Count; i++) {
2926+
var parameterType = GenericParameterResolver.ResolveParameterTypeIfNeeded (
2927+
attribute.Constructor, parameters [i]);
2928+
WriteCustomAttributeFixedArgument (parameterType, arguments [i]);
2929+
}
29272930
}
29282931

29292932
void WriteCustomAttributeFixedArgument (TypeReference type, CustomAttributeArgument argument)

Test/Mono.Cecil.Tests/CustomAttributesTests.cs

+74
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,80 @@ public void GenericParameterConstraint ()
464464
}, verify: !Platform.OnMono);
465465
}
466466

467+
[Test]
468+
public void GenericAttributeString ()
469+
{
470+
TestModule ("GenericAttributes.dll", module => {
471+
var type = module.GetType ("WithGenericAttribute_OfString");
472+
Assert.IsTrue (type.HasCustomAttributes);
473+
var attributes = type.CustomAttributes;
474+
Assert.AreEqual (1, attributes.Count);
475+
Assert.AreEqual ("GenericAttribute`1<System.String>", attributes [0].AttributeType.FullName);
476+
var attribute = attributes [0];
477+
// constructor arguments
478+
Assert.AreEqual (true, attribute.HasConstructorArguments);
479+
var argument = attribute.ConstructorArguments.Single ();
480+
Assert.AreEqual ("System.String", argument.Type.FullName);
481+
Assert.AreEqual ("t", argument.Value);
482+
// named field argument
483+
Assert.AreEqual (true, attribute.HasFields);
484+
var field = attribute.Fields.Single ();
485+
Assert.AreEqual ("F", field.Name);
486+
Assert.AreEqual ("System.String", field.Argument.Type.FullName);
487+
Assert.AreEqual ("f", field.Argument.Value);
488+
// named property argument
489+
Assert.AreEqual (true, attribute.HasProperties);
490+
var property = attribute.Properties.Single ();
491+
Assert.AreEqual ("P", property.Name);
492+
Assert.AreEqual ("System.String", property.Argument.Type.FullName);
493+
Assert.AreEqual ("p", property.Argument.Value);
494+
495+
}, verify: !Platform.OnMono);
496+
}
497+
498+
[Test]
499+
public void GenericAttributeInt ()
500+
{
501+
TestModule ("GenericAttributes.dll", module => {
502+
var type = module.GetType ("WithGenericAttribute_OfInt");
503+
Assert.IsTrue (type.HasCustomAttributes);
504+
var attributes = type.CustomAttributes;
505+
Assert.AreEqual (1, attributes.Count);
506+
Assert.AreEqual ("GenericAttribute`1<System.Int32>", attributes [0].AttributeType.FullName);
507+
var attribute = attributes [0];
508+
// constructor arguments
509+
Assert.AreEqual (true, attribute.HasConstructorArguments);
510+
var argument = attribute.ConstructorArguments.Single ();
511+
Assert.AreEqual ("System.Int32", argument.Type.FullName);
512+
Assert.AreEqual (1, argument.Value);
513+
// named field argument
514+
Assert.AreEqual (true, attribute.HasFields);
515+
var field = attribute.Fields.Single ();
516+
Assert.AreEqual ("F", field.Name);
517+
Assert.AreEqual ("System.Int32", field.Argument.Type.FullName);
518+
Assert.AreEqual (2, field.Argument.Value);
519+
// named property argument
520+
Assert.AreEqual (true, attribute.HasProperties);
521+
var property = attribute.Properties.Single ();
522+
Assert.AreEqual ("P", property.Name);
523+
Assert.AreEqual ("System.Int32", property.Argument.Type.FullName);
524+
Assert.AreEqual (3, property.Argument.Value);
525+
}, verify: !Platform.OnMono);
526+
}
527+
528+
[Test]
529+
public void ConstrainedGenericAttribute ()
530+
{
531+
TestModule ("GenericAttributes.dll", module => {
532+
var type = module.GetType ("WithConstrainedGenericAttribute");
533+
Assert.IsTrue (type.HasCustomAttributes);
534+
var attributes = type.CustomAttributes;
535+
Assert.AreEqual (1, attributes.Count);
536+
var attribute = attributes [0];
537+
Assert.AreEqual ("ConstrainedGenericAttribute`1<DerivedFromConstraintType>", attribute.AttributeType.FullName);
538+
}, verify: !Platform.OnMono);
539+
}
540+
467541
[Test]
468542
public void NullCharInString ()
469543
{
Binary file not shown.

0 commit comments

Comments
 (0)