diff options
author | Sven Boemer <sbomer@gmail.com> | 2022-08-23 14:35:17 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-23 14:35:17 +0300 |
commit | 1840b7410d37a613e684b6f9650e39e2d4950bbb (patch) | |
tree | 4f08afae52d40c673d8c84d7c3cbcf9a07455a53 | |
parent | 2cd569a98964629b8fa88284a8b5af8077d5f9de (diff) |
Add support for generic attributes (#36)
-rw-r--r-- | Mono.Cecil/AssemblyReader.cs | 7 | ||||
-rw-r--r-- | Mono.Cecil/AssemblyWriter.cs | 7 | ||||
-rw-r--r-- | Test/Mono.Cecil.Tests/CustomAttributesTests.cs | 74 | ||||
-rw-r--r-- | Test/Resources/assemblies/GenericAttributes.dll | bin | 0 -> 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 Binary files differnew file mode 100644 index 0000000..1c8e8d6 --- /dev/null +++ b/Test/Resources/assemblies/GenericAttributes.dll |