Skip to content

Commit

Permalink
Add support for generic attributes (#871)
Browse files Browse the repository at this point in the history
* Add support for generic attributes

* Compile test assembly against mscorlib

To satisfy PEVerify
  • Loading branch information
sbomer authored Sep 29, 2022
1 parent 49b1c52 commit 42b9ef1
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 4 deletions.
7 changes: 5 additions & 2 deletions Mono.Cecil/AssemblyReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3513,9 +3513,12 @@ public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute,

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

for (int i = 0; i < count; i++)
for (int i = 0; i < count; i++) {
var parameterType = GenericParameterResolver.ResolveParameterTypeIfNeeded (
attribute.Constructor, parameters [i]);
attribute.arguments.Add (
ReadCustomAttributeFixedArgument (parameters [i].ParameterType));
ReadCustomAttributeFixedArgument (parameterType));
}
}

CustomAttributeArgument ReadCustomAttributeFixedArgument (TypeReference type)
Expand Down
7 changes: 5 additions & 2 deletions Mono.Cecil/AssemblyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2922,8 +2922,11 @@ public void WriteCustomAttributeConstructorArguments (CustomAttribute attribute)
if (parameters.Count != arguments.Count)
throw new InvalidOperationException ();

for (int i = 0; i < arguments.Count; i++)
WriteCustomAttributeFixedArgument (parameters [i].ParameterType, arguments [i]);
for (int i = 0; i < arguments.Count; i++) {
var parameterType = GenericParameterResolver.ResolveParameterTypeIfNeeded (
attribute.Constructor, parameters [i]);
WriteCustomAttributeFixedArgument (parameterType, arguments [i]);
}
}

void WriteCustomAttributeFixedArgument (TypeReference type, CustomAttributeArgument argument)
Expand Down
74 changes: 74 additions & 0 deletions Test/Mono.Cecil.Tests/CustomAttributesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,80 @@ public void GenericParameterConstraint ()
}, verify: !Platform.OnMono);
}

[Test]
public void GenericAttributeString ()
{
TestModule ("GenericAttributes.dll", module => {
var type = module.GetType ("WithGenericAttribute_OfString");
Assert.IsTrue (type.HasCustomAttributes);
var attributes = type.CustomAttributes;
Assert.AreEqual (1, attributes.Count);
Assert.AreEqual ("GenericAttribute`1<System.String>", attributes [0].AttributeType.FullName);
var attribute = attributes [0];
// constructor arguments
Assert.AreEqual (true, attribute.HasConstructorArguments);
var argument = attribute.ConstructorArguments.Single ();
Assert.AreEqual ("System.String", argument.Type.FullName);
Assert.AreEqual ("t", argument.Value);
// named field argument
Assert.AreEqual (true, attribute.HasFields);
var field = attribute.Fields.Single ();
Assert.AreEqual ("F", field.Name);
Assert.AreEqual ("System.String", field.Argument.Type.FullName);
Assert.AreEqual ("f", field.Argument.Value);
// named property argument
Assert.AreEqual (true, attribute.HasProperties);
var property = attribute.Properties.Single ();
Assert.AreEqual ("P", property.Name);
Assert.AreEqual ("System.String", property.Argument.Type.FullName);
Assert.AreEqual ("p", property.Argument.Value);
}, verify: !Platform.OnMono);
}

[Test]
public void GenericAttributeInt ()
{
TestModule ("GenericAttributes.dll", module => {
var type = module.GetType ("WithGenericAttribute_OfInt");
Assert.IsTrue (type.HasCustomAttributes);
var attributes = type.CustomAttributes;
Assert.AreEqual (1, attributes.Count);
Assert.AreEqual ("GenericAttribute`1<System.Int32>", attributes [0].AttributeType.FullName);
var attribute = attributes [0];
// constructor arguments
Assert.AreEqual (true, attribute.HasConstructorArguments);
var argument = attribute.ConstructorArguments.Single ();
Assert.AreEqual ("System.Int32", argument.Type.FullName);
Assert.AreEqual (1, argument.Value);
// named field argument
Assert.AreEqual (true, attribute.HasFields);
var field = attribute.Fields.Single ();
Assert.AreEqual ("F", field.Name);
Assert.AreEqual ("System.Int32", field.Argument.Type.FullName);
Assert.AreEqual (2, field.Argument.Value);
// named property argument
Assert.AreEqual (true, attribute.HasProperties);
var property = attribute.Properties.Single ();
Assert.AreEqual ("P", property.Name);
Assert.AreEqual ("System.Int32", property.Argument.Type.FullName);
Assert.AreEqual (3, property.Argument.Value);
}, verify: !Platform.OnMono);
}

[Test]
public void ConstrainedGenericAttribute ()
{
TestModule ("GenericAttributes.dll", module => {
var type = module.GetType ("WithConstrainedGenericAttribute");
Assert.IsTrue (type.HasCustomAttributes);
var attributes = type.CustomAttributes;
Assert.AreEqual (1, attributes.Count);
var attribute = attributes [0];
Assert.AreEqual ("ConstrainedGenericAttribute`1<DerivedFromConstraintType>", attribute.AttributeType.FullName);
}, verify: !Platform.OnMono);
}

[Test]
public void NullCharInString ()
{
Expand Down
Binary file not shown.

0 comments on commit 42b9ef1

Please sign in to comment.