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

github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Boemer <sbomer@gmail.com>2022-08-23 14:35:17 +0300
committerGitHub <noreply@github.com>2022-08-23 14:35:17 +0300
commit1840b7410d37a613e684b6f9650e39e2d4950bbb (patch)
tree4f08afae52d40c673d8c84d7c3cbcf9a07455a53
parent2cd569a98964629b8fa88284a8b5af8077d5f9de (diff)
Add support for generic attributes (#36)
-rw-r--r--Mono.Cecil/AssemblyReader.cs7
-rw-r--r--Mono.Cecil/AssemblyWriter.cs7
-rw-r--r--Test/Mono.Cecil.Tests/CustomAttributesTests.cs74
-rw-r--r--Test/Resources/assemblies/GenericAttributes.dllbin0 -> 5120 bytes
4 files changed, 84 insertions, 4 deletions
diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs
index ee2c229..4180d78 100644
--- a/Mono.Cecil/AssemblyReader.cs
+++ b/Mono.Cecil/AssemblyReader.cs
@@ -3513,9 +3513,12 @@ namespace Mono.Cecil {
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)
diff --git a/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil/AssemblyWriter.cs
index 3843e85..b8b2b14 100644
--- a/Mono.Cecil/AssemblyWriter.cs
+++ b/Mono.Cecil/AssemblyWriter.cs
@@ -2928,8 +2928,11 @@ namespace Mono.Cecil {
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)
diff --git a/Test/Mono.Cecil.Tests/CustomAttributesTests.cs b/Test/Mono.Cecil.Tests/CustomAttributesTests.cs
index a406c41..00f00ca 100644
--- a/Test/Mono.Cecil.Tests/CustomAttributesTests.cs
+++ b/Test/Mono.Cecil.Tests/CustomAttributesTests.cs
@@ -465,6 +465,80 @@ namespace Mono.Cecil.Tests {
}
[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 ()
{
TestCSharp ("CustomAttributes.cs", module => {
diff --git a/Test/Resources/assemblies/GenericAttributes.dll b/Test/Resources/assemblies/GenericAttributes.dll
new file mode 100644
index 0000000..1c8e8d6
--- /dev/null
+++ b/Test/Resources/assemblies/GenericAttributes.dll
Binary files differ